aboutsummaryrefslogtreecommitdiff
path: root/lib/WebCoso/XSLT.pm
blob: 0d36652d9b1d6bb1febd6efc5b0d44e6d7183406 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package WebCoso::XSLT; 
use strict;
use warnings;
use WebCoso::Common;
use Path::Class;
use XML::LibXML;
use XML::LibXSLT;
use DateTime::Format::Strptime;
use Log::Log4perl ':easy';
 
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->{xslt_proc}->register_function($NS,'dates-for',
                                          sub{$self->getDatesXML(WebCoso::Common::getDatesFor($self->{fc},@_))});
 
    $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)=@_;
        DEBUG("du2html($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) {
            INFO("xml tagging as $deps->[0]");
            $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};
 
    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;
}
 
{
my %name_map=(creation=>'wc:creation-date',
              last_change=>'wc:last-change');
my $format=DateTime::Format::Strptime->new(pattern=>'%F %T',time_zone=>'UTC');
sub getDatesXML {
    my ($self,$dates)=@_;
    my $doc=XML::LibXML::Document->new();
    return $doc unless defined $dates;
 
    my $de=$doc->createElementNS($NS,'wc:dates');
    $doc->setDocumentElement($de);
    while (my ($k,$v)=each %$dates) {
        my $d=$doc->createElementNS($NS,$name_map{$k});
        $d->appendTextNode($format->format_datetime($v));
        $de->appendChild($d);
    }
    return $doc;
}
}
1;