From 2969fd3ef2ac1004ff4594198e84b31c60adb0c5 Mon Sep 17 00:00:00 2001 From: dakkar Date: Thu, 3 Jan 2008 20:35:26 +0000 Subject: refactoring: ReST git-svn-id: svn://luxion/repos/WebCoso/trunk@328 fcb26f47-9200-0410-b104-b98ab5b095f3 --- lib/WebCoso/Common.pm | 59 +++++++++++++++ lib/WebCoso/Maker.pm | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/WebCoso/ReST.pm | 37 ++++++++++ 3 files changed, 297 insertions(+) create mode 100644 lib/WebCoso/Maker.pm create mode 100644 lib/WebCoso/ReST.pm (limited to 'lib/WebCoso') diff --git a/lib/WebCoso/Common.pm b/lib/WebCoso/Common.pm index e6e5ac9..6dbeeae 100644 --- a/lib/WebCoso/Common.pm +++ b/lib/WebCoso/Common.pm @@ -1,12 +1,14 @@ package WebCoso::Common; use strict; use warnings; +use File::Next; use Path::Class; use XML::LibXML::XPathContext; our $SRCPATH='src'; our $DSTPATH='dst'; our $DSTBASEURL='/'; +our @TMPLPATH=('common/'); my $xpath=XML::LibXML::XPathContext->new(); $xpath->registerNs('x', 'http://www.w3.org/1999/xhtml'); @@ -92,4 +94,61 @@ sub getTags { return \%tagged; } +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=( + 'rest.tt'=>0, + 'rest.txt'=>1, + '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); + my $lang=langOf($c->basename); + my $type=typeOf($c->basename); + if (!defined $lang or !defined $type) { + die "Weird document name <$f>"; + } + $dirs{$c->parent}->{$lang}=earliest($type,$dirs{$c->parent}->{$lang}); + } + my @ret; + while (my ($d,$langs)=each %dirs) { + while (my ($lang,$type)=each %$langs) { + push @ret,file($d,"document.$lang.$type")->stringify; + } + } + return @ret; +} +} + +our %docfiles=( + files=>sub{m{^document\.}}, + dirs=>sub{!m{^(tags|_webcoso|\.svn)$}}); + 1; diff --git a/lib/WebCoso/Maker.pm b/lib/WebCoso/Maker.pm new file mode 100644 index 0000000..0561a2c --- /dev/null +++ b/lib/WebCoso/Maker.pm @@ -0,0 +1,201 @@ +package WebCoso::Maker; +use strict; +use warnings; +use Slay::Maker; +use File::Next; +use Path::Class; +use File::Cache::Parsed; +use Cwd 'abs_path'; +use YAML::Syck; +use WebCoso::Common; +use WebCoso::TT; +use WebCoso::XSLT; +use WebCoso::ReST; + +my $fc=File::Cache::Parsed->new(follow=>1); +$fc->add_parser(qr{\.ya?ml$} => + sub { Load($_[1]) }); +$fc->add_writer(qr{\.ya?ml$} => + sub { DumpFile($_[0],$_[1]) }); + +my $template=WebCoso::TT->new(TMPLPATH=>\@WebCoso::Common::TMPLPATH,fc=>$fc); +my $xslt=WebCoso::XSLT->new(fc=>$fc); +my $rest=WebCoso::ReST->new(fc=>$fc); + +sub parseRST { + my ($maker,$target,$deps,$matches)=@_; + + $fc->put($target,$fc->get($deps->[-1])); +} + +sub getTags { + my ($maker,$target,$deps,$matches)=@_; + + $fc->put($target,WebCoso::Common::getTags($fc,@$deps)); +} + +sub getChanges { + my ($maker,$target,$deps,$matches)=@_; + + warn "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; + } +} + +my %maker_opts=( + options => { + auto_create_dirs => 1, + #debug => 1, + }, +); + +my @passes=( + {maker=>Slay::Maker->new({ + rules => [ + + # tags : must come first, otherwise tha "tags" directory will + # be taken as a normal document directory + + ["$WebCoso::Common::SRCPATH/tags/(**)/document.(*).rest.txt", + ':', + "$WebCoso::Common::SRCPATH/_webcoso/tags.yml", + ifExists("$WebCoso::Common::SRCPATH/tags/\$1/document.\$2.rest.tt"), + '=', + $template->expandTT()], + ["$WebCoso::Common::SRCPATH/tags/(**)/document.(*).du.xml", + ':', + "$WebCoso::Common::SRCPATH/_webcoso/tags.yml", + ifExists("$WebCoso::Common::SRCPATH/tags/\$1/document.\$2.rest.txt"), + '=', + \&parseRST], + + # normal documents, in subdirs + + ["$WebCoso::Common::SRCPATH/(**)/document.(*).rest.txt", + ':', + ifExists("$WebCoso::Common::SRCPATH/\$1/document.\$2.rest.tt"), + '=', + $template->expandTT()], + ["$WebCoso::Common::SRCPATH/(**)/document.(*).du.xml", + ':', + ifExists("$WebCoso::Common::SRCPATH/\$1/document.\$2.rest.txt"), + '=', + \&parseRST], + + # normal documents, in top dir + + ["$WebCoso::Common::SRCPATH/()document.(*).rest.txt", + ':', + ifExists("$WebCoso::Common::SRCPATH/document.\$2.rest.tt"), + '=', + $template->expandTT()], + ["$WebCoso::Common::SRCPATH/()document.(*).du.xml", + ':', + ifExists("$WebCoso::Common::SRCPATH/document.\$2.rest.txt"), + '=', + \&parseRST], + + # tags from normal documents (tag documents can't be tagged!) + + ["$WebCoso::Common::SRCPATH/_webcoso/tags.yml", + ':', + WebCoso::Common::fromTo($WebCoso::Common::SRCPATH, + { + %WebCoso::Common::docfiles, + transform=>sub{WebCoso::Common::typedAs($_[0],'du.xml')} + }), + '=', + \&getTags], + + # changes (currently unimplemented) + + ["$WebCoso::Common::SRCPATH/_webcoso/changes.xml", + ':', + WebCoso::Common::keepEarliest( + WebCoso::Common::fromTo( + $WebCoso::Common::SRCPATH,{%WebCoso::Common::docfiles} + ) + ), + '=', + \&getChanges], + ], + %maker_opts, + }), + targets=>[ + WebCoso::Common::fromTo("$WebCoso::Common::SRCPATH/", + { + %WebCoso::Common::docfiles, + transform=>sub{WebCoso::Common::typedAs($_[0],'du.xml')}, + }), + WebCoso::Common::fromTo("$WebCoso::Common::SRCPATH/tags/", + { + %WebCoso::Common::docfiles, + transform=>sub{WebCoso::Common::typedAs($_[0],'du.xml')}, + })]}, + {maker=>Slay::Maker->new({ + rules => [ + + # tags : must come first, otherwise tha "tags" directory will + # be taken as a normal document directory + + ["$WebCoso::Common::DSTPATH/tags/(**)/document.(*).html", + ':', + "$WebCoso::Common::SRCPATH/_webcoso/tags.yml", + "$WebCoso::Common::SRCPATH/tags/\$1/document.\$2.du.xml", + '=', + $xslt->du2html()], + + # normal documents, in subdirs + + ["$WebCoso::Common::DSTPATH/(**)/document.(*).html", + ':', + "$WebCoso::Common::SRCPATH/_webcoso/tags.yml", + "$WebCoso::Common::SRCPATH/\$1/document.\$2.du.xml", + '=', + $xslt->du2html()], + + # normal documents, in top dir + + ["$WebCoso::Common::DSTPATH/()document.(*).html", + ':', + "$WebCoso::Common::SRCPATH/_webcoso/tags.yml", + "$WebCoso::Common::SRCPATH/document.\$2.du.xml", + '=', + $xslt->du2html()], + ], + %maker_opts, + }), + targets=>[WebCoso::Common::fromTo("$WebCoso::Common::SRCPATH/", + { + %WebCoso::Common::docfiles, + transform=>sub{ + (my $file=WebCoso::Common::typedAs($_[0],'html')) + =~s{^\Q$WebCoso::Common::SRCPATH\E/}{$WebCoso::Common::DSTPATH/}; + return $file; + }, + }), + WebCoso::Common::fromTo("$WebCoso::Common::SRCPATH/tags/", + { + %WebCoso::Common::docfiles, + transform=>sub{ + (my $file=WebCoso::Common::typedAs($_[0],'html')) + =~s{^\Q$WebCoso::Common::SRCPATH\E/tags/}{$WebCoso::Common::DSTPATH/tags/}; + return $file; + }, + })]}, +); + +sub make { + $_->{maker}->make(@{$_->{targets}}) for @passes; +} + +1; diff --git a/lib/WebCoso/ReST.pm b/lib/WebCoso/ReST.pm new file mode 100644 index 0000000..bd43528 --- /dev/null +++ b/lib/WebCoso/ReST.pm @@ -0,0 +1,37 @@ +package WebCoso::ReST; +use strict; +use warnings; +use WebCoso::Common; +use Path::Class; +use Text::Restructured; +use Text::Restructured::Writer::LibXML; + +sub new { + my ($class,%opts)=@_; + + my $self={%opts}; + + $self->{rest}=Text::Restructured->new( + { + D=>{ + 'file-insertion-enabled'=>0, # we use TT + generator=>0, + date=>0, + 'time'=>0, + 'source-link'=>0, + 'section-subtitles'=>1, + }, + }, + 'WebCoso'); + + $self->{fc}->add_parser(qr{\.rest\.txt$} => + sub { + my $dudom=$self->{rest}->Parse($_[1],$_[0]); + return Text::Restructured::Writer::LibXML + ->new->ProcessDOM($dudom); + }); + + bless $self,$class; +} + +1; -- cgit v1.2.3