aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/WebCoso/Common.pm49
-rw-r--r--lib/WebCoso/TT.pm2
-rw-r--r--lib/WebCoso/XSLT.pm95
-rw-r--r--script/webcoso.pl121
4 files changed, 152 insertions, 115 deletions
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;
diff --git a/script/webcoso.pl b/script/webcoso.pl
index 4803ac0..657caa8 100644
--- a/script/webcoso.pl
+++ b/script/webcoso.pl
@@ -4,17 +4,15 @@ 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;
-use XML::LibXML;
-use XML::LibXSLT;
use YAML::Syck;
use Getopt::Long;
use WebCoso::Common;
use WebCoso::TT;
+use WebCoso::XSLT;
my @TMPLPATH=('common/');
my $CLEAN=0;
@@ -45,11 +43,6 @@ my $rest=Text::Restructured->new(
},
'WebCoso');
-my $xml_parser=XML::LibXML->new();
-my $xslt_proc=XML::LibXSLT->new();
-my $xpath=XML::LibXML::XPathContext->new();
-$xpath->registerNs('x', 'http://www.w3.org/1999/xhtml');
-
my $fc=File::Cache::Parsed->new(follow=>1);
$fc->add_parser(qr{\.rest\.txt$} =>
sub {
@@ -57,83 +50,13 @@ $fc->add_parser(qr{\.rest\.txt$} =>
return Text::Restructured::Writer::LibXML
->new->ProcessDOM($dudom);
});
-$fc->add_parser(qr{\.xml$} =>
- sub { $xml_parser->parse_string($_[1],$_[0]) });
-$fc->add_parser(qr{\.xslt?$} =>
- sub { $xslt_proc->parse_stylesheet
- ($xml_parser->parse_string($_[1],$_[0])) });
-$fc->add_writer(qr{\.xml$} =>
- sub { $_[1]->toFile($_[0]) });
$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);
-
-sub getTitleFor {
- my ($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$WebCoso::Common::DSTBASEURL\E}) {
- $doc_name=~s{^\Q$WebCoso::Common::DSTBASEURL\E}{$WebCoso::Common::SRCPATH/};
- }
- else {
- $doc_name=file($doc_name)->absolute(file($path)->parent)->relative($WebCoso::Common::SRCPATH); # absolutize it
- $doc_name="$WebCoso::Common::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;
-}
-
-my $NS='http://webcoso.thenautilus.net/';
-
-$xslt_proc->register_function($NS,'title-for',\&getTitleFor);
-
-{my $tags_source;
-sub setXMLTagsSource {$tags_source=shift}
-sub getTagsXML {
- my $doc=XML::LibXML::Document->new();
- return $doc unless defined $tags_source;
-
- warn "getTagsXML()\n";
-
- my $de=$doc->createElementNS($NS,'wc:tags');
- $doc->setDocumentElement($de);
- my ($tagname,$doclist);
- while (($tagname,$doclist)=each %$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;
-}
-}
-$xslt_proc->register_function($NS,'tagged',\&getTagsXML);
+my $xslt=WebCoso::XSLT->new(fc=>$fc);
sub parseRST {
my ($maker,$target,$deps,$matches)=@_;
@@ -141,42 +64,10 @@ sub parseRST {
$fc->put($target,$fc->get($deps->[-1]));
}
-sub du2html {
- my ($maker,$target,$deps,$matches)=@_;
-
- my $du=$fc->get($deps->[-1]);
- my $xslt=file($deps->[-1])->parent->file('du2html.xsl');
- $xslt=$fc->get($xslt);
- if (@$deps>1) {
- warn "xml tagging as $deps->[0]\n";
- setXMLTagsSource($fc->get($deps->[0]));
- }
- else {
- setXMLTagsSource(undef);
- }
- my $out=$xslt->transform($du,
- XML::LibXSLT::xpath_to_string(
- path => $matches->[0],
- language => $matches->[1],
- filename => $deps->[-1],
- ));
- $fc->put($target,$xslt->output_string($out));
-}
-
sub getTags {
my ($maker,$target,$deps,$matches)=@_;
- my %tagged;
- for my $doc_name (@$deps) {
- 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;
- }
- $fc->put($target,\%tagged);
+ $fc->put($target,WebCoso::Common::getTags($fc,@$deps));
}
sub getChanges {
@@ -365,7 +256,7 @@ my @passes=(
"$WebCoso::Common::SRCPATH/_webcoso/tags.yml",
"$WebCoso::Common::SRCPATH/tags/\$1/document.\$2.du.xml",
'=',
- \&du2html],
+ $xslt->du2html()],
# normal documents, in subdirs
@@ -374,7 +265,7 @@ my @passes=(
"$WebCoso::Common::SRCPATH/_webcoso/tags.yml",
"$WebCoso::Common::SRCPATH/\$1/document.\$2.du.xml",
'=',
- \&du2html],
+ $xslt->du2html()],
# normal documents, in top dir
@@ -383,7 +274,7 @@ my @passes=(
"$WebCoso::Common::SRCPATH/_webcoso/tags.yml",
"$WebCoso::Common::SRCPATH/document.\$2.du.xml",
'=',
- \&du2html],
+ $xslt->du2html()],
],
%maker_opts,
}),