#!/usr/local/bin/perl # Copyright (c) 2004-2005, Jan Stocker # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of Jan Stocker nor the names of its contributors may # be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. use strict; use Getopt::Long; use File::Find; use File::Copy; my $source = ''; my $dest = ''; my $framework = ''; my $excludedirs = ''; my $excludefiles = ''; my $htmlfiles = '*.html;*.htm'; my $verbose = 0; my $copyfiles = 1; my $processfiles = 1; my $dirmode = '0775'; my $filemode = '0664'; #Get commandline options if (!GetOptions( 'dirmode|dm=s' => \$dirmode, 'filemode|fm=s' => \$filemode, 'excludedirs|ed=s' => \$excludedirs, 'excludefiles|ef=s' => \$excludefiles, 'htmlfiles|f=s' => \$htmlfiles, 'copy!' => \$copyfiles, 'process!' => \$processfiles, 'verbose|v+' => \$verbose) ) { usage(); exit; } $dirmode = oct($dirmode); $filemode = oct($filemode); if ($excludedirs) { $excludedirs ="/$excludedirs/"; $excludedirs =~s/\?/\[^\/\]/g; $excludedirs =~s/\*/\[^\/\]\*/g; $excludedirs =~s/;/\/|\//g; } if ($excludefiles) { $excludefiles ="/$excludefiles\$"; $excludefiles =~s/\?/\[^\/\]/g; $excludefiles =~s/\*/\[^\/\]\*/g; $excludefiles =~s/;/\$|\//g; } if ($htmlfiles) { $htmlfiles ="^$htmlfiles\$"; $htmlfiles =~s/\?/\[^\/\]/g; $htmlfiles =~s/\*/\[^\/\]\*/g; $htmlfiles =~s/;/\$|\//g; } if ($#ARGV != 1) { usage(); exit; } $source = File::Spec->rel2abs($ARGV[0]); $dest = File::Spec->rel2abs($ARGV[1]); my $fw_use = ''; my %fw_vars = {}; my $context = 'global'; reversemkdir($dest); #process all files/dirs finddepth(\&processfiles, $source); #Print usage sub usage { print < where options can be: -dm | -dirmode= directory creation mode (0775) -fm | -filemode= file creation mode (0664) -ed | -excludedirs= exclude dirs, comma separated -ef | -excludefiles= exclude files, comma separated -f | -htmlfiles= html files, comma separated ("*.htm;*.html") -noprocess ignore html files -nocopy ignore non html files -v verbose: copy and process msgs) -v -v verbose: copy, process and ignore msgs -v -v -v verbose: above and process tag msgs EOB } #Create a given directory sub reversemkdir { my($dir) = @_; -e $dir && return; $_ = $dir; if (/(.*)\/[^\/]*\$/) { reversemkdir($1); } mkdir($dir) && chmod($dirmode, $dir); } #Parse html files / copy non html files sub processfiles { -d $File::Find::name && return; my($filename) = $_; $_ = $File::Find::name; if ( ($excludedirs && /$excludedirs/) ||($excludefiles && /$excludefiles/)) { $verbose > 1 and print "Ignore file '".$File::Find::name."'\n"; return; } my($relpath) = $File::Find::dir; $relpath=~s/^$source//; $relpath=~s/^\///; $relpath && reversemkdir($dest.'/'.$relpath); my($filepath) = $File::Find::name; $filepath=~s/^$source//; $filepath=~s/^\///; $_ = $filename; #Process HTML files if (/$htmlfiles/) { not $processfiles and return; $fw_use = ''; %fw_vars = {}; $context = 'global'; $verbose > 0 and print "Process HTML file '$source/$filepath' --> '$dest/$filepath'\n"; my($html) = loadhtml($source.'/'.$filepath); if ($fw_use) { $fw_vars{'global'} = ''; my($htmlframework) = loadhtml($fw_use); $html = compilehtml($html, $htmlframework); } my($destfile) = $dest.'/'.$filepath; open(HTMLDEST, ">$destfile") or die "File open failed: '$destfile'!"; print(HTMLDEST $html); close(HTMLDEST); chmod($filemode, $destfile); } #All other files will be copied else { not $copyfiles and return; $verbose > 0 and print "Copy file '$source/$filepath' --> '$dest/$filepath'\n"; copy($source.'/'.$filepath, $dest.'/'.$filepath) || die "Copy failed: '$source/$filepath' --> '$dest/$filepath'"; chmod($filemode, $dest.'/'.$filepath); } } #Load file and parse for tags sub loadhtml { my($htmlfile) = @_; open(HTMLSOURCE, $htmlfile); while () { while ($_) { if(/(]*>)/i) { $fw_vars{$context}.=$`; my($tail) = $'; $_ = $1; if (/DEFINE[ ]*=[ ]*"([^"]*)".*/i) { $context = $1; if (/\/>\$/) { $context = 'global'; } $verbose > 2 and print "CMS: File='$htmlfile' DEFINE='$context'\n"; } elsif (/INCLUDE[ ]*=[ ]*"([^"]*)".*/i) { my($includefile) = $htmlfile; $includefile =~s/\/[^\/]*$//; $includefile.='/'.$1; $fw_vars{$context}.=loadhtml($includefile); $verbose > 2 and print "CMS: File='$htmlfile' Context='$context' INCLUDE='$includefile'\n"; } elsif (/USE[ ]*=[ ]*"([^"]*)".*/i) { my($usefile) = $1; my($absusefile) = $htmlfile; $absusefile =~s/\/[^\/]*$//; $absusefile.='/'.$usefile; $fw_use = $absusefile; $verbose > 2 and print "CMS: File='$htmlfile' USE='$absusefile'\n"; } else { $fw_vars{$context}.=$1; } $_= $tail; } elsif(/<\/FW>/i) { $fw_vars{$context}.=$`; my($tail) = $'; $context = 'global'; $_= $tail; } else { $fw_vars{$context}.=$_; $_=''; } } } close(HTMLSOURCE); return $fw_vars{'global'}; } #Create HTML file with a framework template sub compilehtml { my($html, $htmlframework) = @_; my($complete) = ''; $_ =$htmlframework; while($_) { if(/(]*>)/i) { $complete.=$`; my($tail) = $'; $_ = $1; if (/PRINT[ ]*=[ ]*"([^"]*)".*/i) { $complete.=$fw_vars{$1}; $verbose > 2 and print "CMS: PRINT='$1'\n"; } else { $complete.=$1; } $_= $tail; } elsif(/<\/FW>/i) { $complete.=$`; $_ = $'; } else { $complete.=$_; $_=''; } } return $complete; }