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 +++++++ script/webcoso.pl | 275 ++------------------------------------------------ 4 files changed, 304 insertions(+), 268 deletions(-) create mode 100644 lib/WebCoso/Maker.pm create mode 100644 lib/WebCoso/ReST.pm 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; diff --git a/script/webcoso.pl b/script/webcoso.pl index 657caa8..0e888d4 100644 --- a/script/webcoso.pl +++ b/script/webcoso.pl @@ -1,27 +1,18 @@ #!/usr/bin/perl use strict; use warnings; -use Slay::Maker; use File::Next; use Path::Class; -use File::Cache::Parsed; -use Cwd 'abs_path'; -use Text::Restructured; -use Text::Restructured::Writer::LibXML; -use YAML::Syck; use Getopt::Long; use WebCoso::Common; -use WebCoso::TT; -use WebCoso::XSLT; -my @TMPLPATH=('common/'); my $CLEAN=0; { my $res=GetOptions('src|s=s'=>\$WebCoso::Common::SRCPATH, 'dst|d=s'=>\$WebCoso::Common::DSTPATH, 'url|u=s'=>\$WebCoso::Common::DSTBASEURL, - 'include|I=s'=>\@TMPLPATH, + 'include|I=s'=>\@WebCoso::Common::TMPLPATH, 'clean'=>\$CLEAN, ); exit 1 unless $res; @@ -30,124 +21,10 @@ $WebCoso::Common::DSTPATH=~s{/+$}{}; $WebCoso::Common::DSTBASEURL=~s{/*$}{/}; } -my $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'); - -my $fc=File::Cache::Parsed->new(follow=>1); -$fc->add_parser(qr{\.rest\.txt$} => - sub { - my $dudom=$rest->Parse($_[1],$_[0]); - return Text::Restructured::Writer::LibXML - ->new->ProcessDOM($dudom); - }); -$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=>\@TMPLPATH,fc=>$fc); -my $xslt=WebCoso::XSLT->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; - } -} - -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=WebCoso::Common::langOf($c->basename); - my $type=WebCoso::Common::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; -} -} - -my %docfiles=( - files=>sub{m{^document\.}}, - dirs=>sub{!m{^(tags|_webcoso|\.svn)$}}); - if ($CLEAN) { my %to_keep; - @to_keep{keepEarliest(fromTo($WebCoso::Common::SRCPATH,{%docfiles,dirs=>sub{!m{^(_webcoso|\.svn)$}}}))}=(); - @to_keep{fromTo($WebCoso::Common::SRCPATH,{files=>sub{!m{^document\.}},dirs=>sub{!m{^(_webcoso|\.svn)$}}})}=(); + @to_keep{WebCoso::Common::keepEarliest(WebCoso::Common::fromTo($WebCoso::Common::SRCPATH,{%WebCoso::Common::docfiles,dirs=>sub{!m{^(_webcoso|\.svn)$}}}))}=(); + @to_keep{WebCoso::Common::fromTo($WebCoso::Common::SRCPATH,{files=>sub{!m{^document\.}},dirs=>sub{!m{^(_webcoso|\.svn)$}}})}=(); my $iter=File::Next::files({descend_filter=>sub{!m{^\.svn$}}},$WebCoso::Common::SRCPATH,$WebCoso::Common::DSTPATH); while (defined (my $file=$iter->())) { @@ -158,145 +35,7 @@ if ($CLEAN) { dir($WebCoso::Common::SRCPATH,'_webcoso')->rmtree; exit 0; } - -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", - ':', - fromTo($WebCoso::Common::SRCPATH, - { - %docfiles, - transform=>sub{WebCoso::Common::typedAs($_[0],'du.xml')} - }), - '=', - \&getTags], - - # changes (currently unimplemented) - - ["$WebCoso::Common::SRCPATH/_webcoso/changes.xml", - ':', - keepEarliest(fromTo($WebCoso::Common::SRCPATH,{%docfiles})), - '=', - \&getChanges], - ], - %maker_opts, - }), - targets=>[ - fromTo("$WebCoso::Common::SRCPATH/", - { - %docfiles, - transform=>sub{WebCoso::Common::typedAs($_[0],'du.xml')}, - }), - fromTo("$WebCoso::Common::SRCPATH/tags/", - { - %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=>[fromTo("$WebCoso::Common::SRCPATH/", - { - %docfiles, - transform=>sub{ - (my $file=WebCoso::Common::typedAs($_[0],'html')) - =~s{^\Q$WebCoso::Common::SRCPATH\E/}{$WebCoso::Common::DSTPATH/}; - return $file; - }, - }), - fromTo("$WebCoso::Common::SRCPATH/tags/", - { - %docfiles, - transform=>sub{ - (my $file=WebCoso::Common::typedAs($_[0],'html')) - =~s{^\Q$WebCoso::Common::SRCPATH\E/tags/}{$WebCoso::Common::DSTPATH/tags/}; - return $file; - }, - })]}, -); - -$_->{maker}->make(@{$_->{targets}}) for @passes; - +else { + require WebCoso::Maker; + WebCoso::Maker::make(); +} -- cgit v1.2.3