#!/usr/bin/perl -w use strict; use lib './lib'; use Template; use Template::Context; use Template::Exception; use FindProvider; use Cwd; use File::Basename; use File::Find; use File::Copy; my $cwd = getcwd; my $incpath = "$cwd/src"; my $outpath = "$cwd/build"; my %names; my %shortnames; my (@paths); open(CONFIG,"< process.files") or die "Cannot open process.files: $!"; while () { next if /^\s*#/ || /^$/; chomp; my ($path,$name) = split / /,$_,2; push @paths,$path; if ($name =~ /(.+)\|(.+)/) { $names{$path} = $1; $shortnames{$path} = $2; } else { $names{$path} = $name; $shortnames{$path} = $name; } warn "$path => $name\n"; } close CONFIG; my $provider = FindProvider->new({ INCLUDE_PATH => $incpath, ABSOLUTE => 1, }); my $context = Template::Context->new({ EVAL_PERL => 1, INCLUDE_PATH => $incpath, LOAD_TEMPLATES => [$provider], }); my $tt = Template->new({ CONTEXT => $context, OUTPUT_PATH => $outpath, }); if (-d $outpath) { warn "Removing build dir\n"; system ("rm -rf $outpath") == 0 or die "Cannot remove $outpath: $!"; } warn "Creating build dir"; mkdir $outpath,0755 or die "Cannot create $outpath: $!"; for my $file (@paths) { my ($base,$dir,$sfx) = fileparse($file,".html"); chdir "$incpath/$dir" or die "Cannot chdir to $dir: $!"; unless (-d "$outpath/$dir") { mkdir "$outpath/$dir",0755 or die "Cannot make $outpath/$dir: $!"; } warn "Processing $dir/$base$sfx\n"; $tt->process("$base$sfx",{ path => $file, title => $names{$file}, short => $shortnames{$file}, paths => \@paths, find => \&find_template, parent => \&parent, children => \&children, titles => \%names, short => \%shortnames, root => root($file), subnav => [subnav($file)], dir => \&dir, top => \&top, },"$dir/$base$sfx") || die $tt->error; } chdir $incpath; find({ wanted => sub { return unless /(?:\.css|\.png|\.jpg|\.pdf|\.txt|\.ico|\.cgi|\.asc)$/; return unless -f $_; warn "Copying $_\n"; copy($_,"$outpath/$_") or die "Cannot copy $_: $!"; }, no_chdir => 1, },'.'); sub find_template { my ($file) = @_; my $cwd = getcwd; my $rel = $file; warn "cwd = $cwd, rel = $file"; while (index($cwd,$incpath) == 0) { if (-f "$cwd/$file") { return $rel; } $cwd =~ s#/[^/]+/?$## or last; $rel = "../$rel"; } die Template::Exception->new('find error',"Cannot find $file anywhere in path\n"); } sub parent { my ($path) = @_; return unless $path =~ m#/#; $path =~ s#/[^/]+/?$##; $path .= "/index.html"; return $path if $names{$path}; return; } sub children { my ($path) = @_; $path =~ s#[^/]+$##; my @children; for (@paths) { if (m#^\Q$path\E[^/]+/[^/]+$#) { push @children,$_; warn "child: $_\n"; } } return @children; } sub root { my ($path) = @_; warn "path =$path"; $path =~ s#^\./##; $path =~ s#[^/]+$##; $path =~ s#[^/]+#..#g; return $path; } sub subnav { my $file = shift; if ($file =~ m#/#) { return children(top($file)); } } sub top { my $file = shift; if ($file !~ m#/#) { return $file; } if ($file =~ m#^([^/]+)/index\.html#) { return $file; } if ($file =~ m#^([^/]+)/#) { return "$1/index.html"; } die "No top"; } sub dir { my $file = shift; $file =~ s/index\.html$//; return $file; } #### package FindProvider; use strict; use base qw(Template::Provider); use Template::Constants qw(STATUS_DECLINED); use Cwd qw(); use File::Basename; sub fetch { my ($self,$filename) = @_; if (ref $filename or index($filename,'..') >= 0 or index($filename,'/') >= 0) { return $self->SUPER::fetch($filename); } my $path = ${$self->paths()}[0]; my $cwd = Cwd::getcwd(); while (index($cwd,$path) ==0) { # only recurse if current directory is in the first path if (-f "$cwd/$filename") { return $self->SUPER::fetch("$cwd/$filename"); } $cwd =~ s#/[^/]+/?$##; } return undef,STATUS_DECLINED; } 1;