From 57517de73fdc8c9035726996f1a99b3493541a31 Mon Sep 17 00:00:00 2001 From: dakkar Date: Thu, 3 Jan 2008 20:23:56 +0000 Subject: refactoring: xslt git-svn-id: svn://luxion/repos/WebCoso/trunk@327 fcb26f47-9200-0410-b104-b98ab5b095f3 --- lib/WebCoso/Common.pm | 49 ++++++++++++++++++++++++++ lib/WebCoso/TT.pm | 2 ++ lib/WebCoso/XSLT.pm | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 lib/WebCoso/XSLT.pm (limited to 'lib/WebCoso') diff --git a/lib/WebCoso/Common.pm b/lib/WebCoso/Common.pm index 0680550..e6e5ac9 100644 --- a/lib/WebCoso/Common.pm +++ b/lib/WebCoso/Common.pm @@ -1,9 +1,16 @@ package WebCoso::Common; +use strict; +use warnings; +use Path::Class; +use XML::LibXML::XPathContext; our $SRCPATH='src'; our $DSTPATH='dst'; our $DSTBASEURL='/'; +my $xpath=XML::LibXML::XPathContext->new(); +$xpath->registerNs('x', 'http://www.w3.org/1999/xhtml'); + sub langOf { my ($name)=@_; $name=~m{(^|/)document\.([^.]+)(\.|$)} and return $2; @@ -43,4 +50,46 @@ sub isLang { return; } +sub getTitleFor { + my ($fc,$lang,$path,$name)=@_; + + my $doc_name=$name; + $doc_name=~s{\.html$}{.du.xml}; + $doc_name=~s{/$}{/document.$lang.du.xml}; + if ($doc_name=~m{^\Q$DSTBASEURL\E}) { + $doc_name=~s{^\Q$DSTBASEURL\E}{$SRCPATH/}; + } + else { + $doc_name=file($doc_name)->absolute(file($path)->parent)->relative($SRCPATH); # absolutize it + $doc_name="$SRCPATH/$doc_name"; + } + warn "getTitleFor($lang,$path,$name)->$doc_name\n"; + + my $doc=$fc->get($doc_name); + unless ($doc) { + warn "No document for <$doc_name>, returning <$name>\n"; + return $name; + } + my $title=$xpath->findnodes( + q{/document/title}, + $doc); + return $title; +} + +sub getTags { + my ($fc,@docs)=@_; + + my %tagged; + for my $doc_name (@docs) { + my $doc=$fc->get($doc_name); + my @tags=map {$_->textContent} + $xpath->findnodes( + q{/document/docinfo/field[field_name='tags']/field_body/*/list_item}, + $doc); + chomp for @tags; + push @{$tagged{$_}},$doc_name for @tags; + } + return \%tagged; +} + 1; diff --git a/lib/WebCoso/TT.pm b/lib/WebCoso/TT.pm index d04c209..fc5d114 100644 --- a/lib/WebCoso/TT.pm +++ b/lib/WebCoso/TT.pm @@ -1,4 +1,6 @@ package WebCoso::TT; +use strict; +use warnings; use WebCoso::Common; use Path::Class; use Template; diff --git a/lib/WebCoso/XSLT.pm b/lib/WebCoso/XSLT.pm new file mode 100644 index 0000000..18d2416 --- /dev/null +++ b/lib/WebCoso/XSLT.pm @@ -0,0 +1,95 @@ +package WebCoso::XSLT; +use strict; +use warnings; +use WebCoso::Common; +use Path::Class; +use XML::LibXML; +use XML::LibXSLT; + +my $NS='http://webcoso.thenautilus.net/'; + +sub new { + my ($class,%opts)=@_; + + my $self={%opts}; + + $self->{xml_parser}=XML::LibXML->new(); + $self->{xslt_proc}=XML::LibXSLT->new(); + + $self->{xslt_proc}->register_function($NS,'title-for', + sub{WebCoso::Common::getTitleFor($self->{fc},@_)}); + $self->{xslt_proc}->register_function($NS,'tagged',sub{$self->getTagsXML}); + + $self->{fc}->add_parser(qr{\.xml$} => + sub { $self->{xml_parser}->parse_string($_[1],$_[0]) }); + $self->{fc}->add_parser(qr{\.xslt?$} => + sub { $self->{xslt_proc}->parse_stylesheet + ($self->{xml_parser}->parse_string($_[1],$_[0])) }); + $self->{fc}->add_writer(qr{\.xml$} => + sub { $_[1]->toFile($_[0]) }); + + $self->{du2html}=sub { + my ($maker,$target,$deps,$matches)=@_; + + my $du=$self->{fc}->get($deps->[-1]); + my $xslt=file($deps->[-1])->parent->file('du2html.xsl'); + $xslt=$self->{fc}->get($xslt); + if (@$deps>1) { + warn "xml tagging as $deps->[0]\n"; + $self->setXMLTagsSource($self->{fc}->get($deps->[0])); + } else { + $self->setXMLTagsSource(undef); + } + my $out=$xslt->transform($du, + XML::LibXSLT::xpath_to_string( + path => $matches->[0], + language => $matches->[1], + filename => $deps->[-1], + )); + $self->{fc}->put($target,$xslt->output_string($out)); + }; + + bless $self,$class; +} + +sub du2html { + my ($self)=@_; + return $self->{du2html}; +} + +sub setXMLTagsSource { + my ($self,$source)=@_; + $self->{tags_source}=$source; +} +sub getTagsXML { + my ($self)=@_; + my $doc=XML::LibXML::Document->new(); + return $doc unless defined $self->{tags_source}; + + warn "getTagsXML()\n"; + + my $de=$doc->createElementNS($NS,'wc:tags'); + $doc->setDocumentElement($de); + my ($tagname,$doclist); + while (($tagname,$doclist)=each %{$self->{tags_source}}) { + my $te=$doc->createElementNS($NS,'wc:tag'); + $te->setAttribute('name',$tagname); + $de->appendChild($te); + my %docs; + push @{$docs{WebCoso::Common::dstUriFor($_)}},WebCoso::Common::langOf($_) for @$doclist; + my ($docurl,$langs); + while (($docurl,$langs)=each %docs) { + my $dle=$doc->createElementNS($NS,'wc:doc'); + $dle->setAttribute('uri',$docurl); + $te->appendChild($dle); + for my $lang (@$langs) { + my $le=$doc->createElementNS($NS,'wc:lang'); + $le->appendTextNode($lang); + $dle->appendChild($le); + } + } + } + return $doc; +} + +1; -- cgit v1.2.3