use strict;
use warnings;
use Slay::Maker;
use File::Next;
use Path::Class;
use Template;
use File::Cache::Parsed;
use Cwd 'abs_path';
use Text::Restructured;
use Text::Restructured::Writer::LibXML;
my $stash={};
my $template=Template->new();
my $rest=Text::Restructured->new({},'WebCoso');
my $fc=File::Cache::Parsed->new();
$fc->add_parser(qr{\.rest\.tt2?$} =>
sub {
my ($name,$content)=@_;
my $real_name=abs_path($name);
my $output;
$template->process($real_name,
{%$stash,name=>$name},
\$output);
return $output;
});
$fc->add_parser(qr{\.rest\.txt$} =>
sub {
my ($name,$content)=@_;
my $dudom=$rest->Parse($content,$name);
return Text::Restructured::Writer::LibXML
->new->ProcessDOM($dudom);
});
sub expandTT {
my ($maker,$target,$deps,$matches)=@_;
print "TT: $target <- @$deps, @$matches\n";
open my $fh,'>',$target;
}
sub parseRST {
my ($maker,$target,$deps,$matches)=@_;
print "RST: $target <- @$deps, @$matches\n";
open my $fh,'>',$target;
}
sub du2html {
my ($maker,$target,$deps,$matches)=@_;
print "HTML: $target <- @$deps, @$matches\n";
open my $fh,'>',$target;
}
sub getTags {
my ($maker,$target,$deps,$matches)=@_;
print "tags: $target <- @$deps, @$matches\n";
open my $fh,'>',$target;
}
sub getChanges {
my ($maker,$target,$deps,$matches)=@_;
print "changes: $target <- @$deps, @$matches\n";
open my $fh,'>',$target;
}
sub ifExists {
my ($src)=@_;
return sub {
my ($maker,$target,$matches)=@_;
my $dep=Slay::MakerRule::var_expand_dep($src,$target,$matches);
return if -e $target and ! -e $dep;
return $dep;
}
}
sub fromTo {
my ($base,$opts)=@_;
my $iter=File::Next::files(
{
file_filter=>$opts->{files},
descend_filter=>$opts->{dirs},
},
$base);
my (@ret,$file);
if (defined $opts->{transform}) {
push @ret,$opts->{transform}->($file) while $file=$iter->();
}
else {
push @ret,$file while $file=$iter->();
}
return @ret;
}
{
my %order=(
'document.rest.tt'=>0,
'document.rest.txt'=>1,
'document.du.xml'=>2,
);
sub earliest {
my ($a,$b)=@_;
return $a unless $b;
return $order{$a} < $order{$b}
? $a
: $b;
}
}
sub keepEarliest {
my %dirs;
for my $f (@_) {
my $c=file($f);
$dirs{$c->parent}=earliest($c->basename,$dirs{$c->parent});
}
my @ret;
while (my ($d,$f)=each %dirs) {
push @ret,file($d,$f)->stringify;
}
return @ret;
}
my %files=(files=>sub{m{^document\.}});
my $maker=Slay::Maker->new({
rules => [
['src/(**)/document.rest.txt',':',ifExists('src/$1/document.rest.tt'),'=',\&expandTT],
['src/(**)/document.du.xml',':',ifExists('src/$1/document.rest.txt'),'=',\&parseRST],
['deps/tags.xml',':',fromTo('src/',{%files,transform=>sub{my $s=shift;$s=~s{\..*$}{.du.xml};$s}}),'=',\&getTags],
['deps/changes.xml',':',keepEarliest(fromTo('src/',{%files})),'=',\&getChanges],
['dst/(**)/document.xhtml',':','deps/tags.xml','deps/changes.xml',ifExists('src/$1/document.du.xml'),'=',\&du2html],
],
options => {
auto_create_dirs => 1,
},
});
my @targets=fromTo('src/',
{
%files,
transform=>sub{
my $src=shift;
$src=~s{\..*$}{.xhtml};
$src=~s{^src/}{dst/};
return $src;
},
});
print "targets: @targets\n";
$maker->make(@targets);