This is an automated email from the git hooks/post-receive script.

intrigeri pushed a commit to tag debian_version_0_4-1
in repository libparse-debianchangelog-perl.

commit 6d0d728e3de3cb26bb31795ba8c19dc48188a799
Author: Frank Lichtenheld <fr...@lichtenheld.de>
Date:   Tue Jul 5 01:40:03 2005 +0000

      * New upstream release
        - adapt Build-Depends-Indep and Recommends to new requirements
        - install new TODO file
        - install templates and CSS files to
          /usr/share/libparse-debianchangelog-perl/ and adapt the default
          paths in the module
---
 debian/changelog             |  11 +
 debian/control               |   4 +-
 debian/install               |   1 +
 debian/rules                 |   3 +-
 lib/Parse/DebianChangelog.pm | 648 +++++++++++++++++++++++++++++++------------
 t/Parse-DebianChangelog.t    |  44 ++-
 6 files changed, 530 insertions(+), 181 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index e3c4e03..cbadea5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,14 @@
+libparse-debianchangelog-perl (0.4-1) unstable; urgency=low
+
+  * New upstream release
+    - adapt Build-Depends-Indep and Recommends to new requirements
+    - install new TODO file
+    - install templates and CSS files to
+      /usr/share/libparse-debianchangelog-perl/ and adapt the default
+      paths in the module
+
+ -- Frank Lichtenheld <dj...@debian.org>  Tue,  5 Jul 2005 03:28:10 +0200
+
 libparse-debianchangelog-perl (0.3a-1) unstable; urgency=low
 
   * Initial Release (Closes: #314559).
diff --git a/debian/control b/debian/control
index 963fb36..e9ed9d3 100644
--- a/debian/control
+++ b/debian/control
@@ -2,14 +2,14 @@ Source: libparse-debianchangelog-perl
 Section: perl
 Priority: optional
 Build-Depends: debhelper (>= 4.0.2)
-Build-Depends-Indep: perl (>= 5.8.0-7), libtimedate-perl
+Build-Depends-Indep: perl (>= 5.8.0-7), libtimedate-perl, libhtml-parser-perl, 
libhtml-template-perl, tidy
 Maintainer: Frank Lichtenheld <dj...@debian.org>
 Standards-Version: 3.6.2
 
 Package: libparse-debianchangelog-perl
 Architecture: all
 Depends: ${perl:Depends}, ${misc:Depends}, libtimedate-perl
-Recommends: dpkg-dev, libhtml-parser-perl, liburi-perl
+Recommends: libhtml-parser-perl, libhtml-template-perl
 Description: parse Debian changelogs and output them in other formats
  Replacement for the very limited dpkg-parsechangelog.
  .
diff --git a/debian/install b/debian/install
new file mode 100644
index 0000000..19290db
--- /dev/null
+++ b/debian/install
@@ -0,0 +1 @@
+tmpl/* usr/share/libparse-debianchangelog-perl
diff --git a/debian/rules b/debian/rules
index f86eb26..a6035df 100755
--- a/debian/rules
+++ b/debian/rules
@@ -59,8 +59,9 @@ binary-arch:
 binary-indep: build install
        dh_testdir
        dh_testroot
+       dh_install
 #      dh_installexamples
-       dh_installdocs
+       dh_installdocs TODO
        dh_installchangelogs Changes
        dh_perl
        dh_link
diff --git a/lib/Parse/DebianChangelog.pm b/lib/Parse/DebianChangelog.pm
index e607c90..0e2e7e9 100644
--- a/lib/Parse/DebianChangelog.pm
+++ b/lib/Parse/DebianChangelog.pm
@@ -29,17 +29,68 @@ Parse::DebianChangelog - parse Debian changelogs and output 
them in other format
 
     my $chglog = Parse::DebianChangelog->init( { infile => 'debian/changelog',
                                                  HTML => { outfile => 
'changelog.html' } );
-    $chglog->html_out;
+    $chglog->html;
 
     # the following is semantically equivalent
     my $chglog = Parse::DebianChangelog->init();
     $chglog->parse( { infile => 'debian/changelog' } );
-    $chglog->html_out( { outfile => 'changelog.html' } );
-    $chglog->dpkg_out( { since => '1.0-1' } );
+    $chglog->html( { outfile => 'changelog.html' } );
 
+    my $changes = $chglog->dpkg_str( { since => '1.0-1' } );
+    print $changes;
 
 =head1 DESCRIPTION
 
+Parse::DebianChangelog parses Debian changelogs as desribed in the Debian
+policy (version 3.6.2.1 at the time of this writing). See section
+L<"SEE ALSO"> for locations where to find this definition.
+
+The parser tries to ignore most cruft like # or /* */ style comments,
+CVS comments, vim variables, emacs local variables and stuff from
+older changelogs with other formats at the end of the file.
+NOTE: most of these are ignored silently currently, there is no
+parser error issued for them. This should become configurable in the
+future.
+
+Parse::DebianChangelog also supports converting these changelogs then
+to various other formats. These are currently:
+
+=over 4
+
+=item dpkg
+
+Format as know from L<dpkg-parsechangelog(1)>. All requested entries
+(see L<"METHODS"> for an explanation what this means) are returned in
+the usual Debian control format, merged in one stanza, ready to be used
+a F<.changes> file.
+
+=item rfc822
+
+Similar to the C<dpkg> format, but the requested entries are returned
+as one stanza each, i.e. they are not merged. This is probably the format
+to use if you want a machine-usable representation of the changelog.
+
+=item html
+
+The changelog is converted to a somewhat nice looking HTML file with
+some niće features as a quicklink bar with direct links to every entry.
+NOTE: This is not very configurable yet and was specifically designed
+to be used on L<http://packages.debian.org/>. This is planned to be
+changed until version 1.0.
+
+=item custom
+
+All the nitty-gritty details of what the parser found out in a
+machine-usable format.
+NOTE: Not implemented yet. You can of course use the internal
+representation but don't expect that to work in future versions of
+this module. It is planned to encapsulate each entry's data in an
+own object and then make these available to the user...
+
+=back
+
+=head2 METHODS
+
 =cut
 
 package Parse::DebianChangelog;
@@ -66,7 +117,22 @@ our @EXPORT = qw(
 );
 
 our $CLASSNAME = 'Parse::DebianChangelog';
-our $VERSION = 0.3;
+our $VERSION = 0.4;
+
+=pod
+
+=head3 init
+
+Creates a new object instance. Takes a reference to a hash as
+optional argument, which is interpreted as configuration options.
+There are currently no supported general configuration options, but
+see the other methods for more specifc configuration options which
+can also specified to C<init>.
+
+If C<infile> is specified (see L<parse>), C<parse()> is called
+from C<init>.
+
+=cut
 
 sub init {
     my $classname = shift;
@@ -85,13 +151,22 @@ sub init {
     return $self;
 }
 
+=pod
+
+=head3 reset_parse_errors
+
+Can be used to delete all information about errors ocurred during
+previous L<parse> runs. Note that C<parse()> also calls this method.
+
+=cut
+
 sub reset_parse_errors {
     my ($self) = @_;
 
     $self->{errors}{parser} = [];
 }
 
-sub do_parse_error {
+sub _do_parse_error {
     my ($self, $file, $line_nr, $error, $line) = @_;
     shift;
 
@@ -107,6 +182,40 @@ sub do_parse_error {
     }
 }
 
+=pod
+
+=head3 get_parse_errors
+
+Returns all error messages from the last L<parse> run.
+If called in scalar context returns a human readable
+string represenation. If called in list context returns
+a reference to an array of arrays. Each of these arrays contains
+
+=over 4
+
+=item 1.
+
+the filename of the parsed file
+
+=item 2.
+
+the line number where the error occoured
+
+=item 3.
+
+an error description
+
+=item 4.
+
+the original line
+
+=back
+
+NOTE: This format isn't stable yet and may change in later versions
+of this module.
+
+=cut
+
 sub get_parse_errors {
     my ($self) = @_;
 
@@ -125,6 +234,31 @@ sub get_parse_errors {
     }
 }
 
+sub __find_closes {
+    my $changes = shift;
+    my @closes = ();
+
+    while ($changes && ($changes =~ 
/closes:\s*(?:bug)?\#?\s?\d+(?:,\s*(?:bug)?\#?\s?\d+)*/ig)) {
+       push(@closes, $& =~ /\#?\s?(\d+)/g);
+    }
+    
+    @closes = sort { $a <=> $b } @closes;
+    return \@closes;
+}
+
+=pod
+
+=head3 parse
+
+Parses the file that is saved in the configuration item C<infile>.
+Accepts a hash ref as optional argument which can contains configuration
+items.
+
+Returns undef in case of error (e.g. "file not found", B<not> parse errors)
+and the object if successfull.
+
+=cut
+
 sub parse {
     my ($self, $config) = @_;
 
@@ -154,14 +288,10 @@ sub parse {
                    || $expect eq 'next heading or eof') {
                $entry{ERROR} = [ $file, $NR,
                                  "found start of entry where expected 
$expect", "$_" ];
-               $self->do_parse_error(@{$entry{ERROR}});
+               $self->_do_parse_error(@{$entry{ERROR}});
            }
            if (%entry) {
-               my @closes;
-               while ($entry{'Changes'} && ($entry{'Changes'} =~ 
/closes:\s*(?:bug)?\#?\s?\d+(?:,\s*(?:bug)?\#?\s?\d+)*/ig)) {
-                   push(@closes, $& =~ /\#?\s?(\d+)/g);
-               }
-               $entry{'Closes'} = [ sort { $a <=> $b } @closes ];
+               $entry{'Closes'} = __find_closes( $entry{Changes} );
                
 #                  print STDERR, Dumper(%entry);
                push @{$self->{data}}, { %entry };
@@ -180,14 +310,14 @@ sub parse {
 #          print STDERR "RHS: $rhs\n";
            for my $kv (split(/\s*,\s*/,$rhs)) {
                $kv =~ m/^([-0-9a-z]+)\=\s*(.*\S)$/i ||
-                   $self->do_parse_error($file, $NR, "bad key-value after 
\`;': \`$kv'");
+                   $self->_do_parse_error($file, $NR, "bad key-value after 
\`;': \`$kv'");
                my $k = ucfirst $1;
                my $v = $2;
-               $kvdone{$k}++ && $self->do_parse_error($file, $NR,
+               $kvdone{$k}++ && $self->_do_parse_error($file, $NR,
                                                       "repeated key-value $k");
                if ($k eq 'Urgency') {
                    $v =~ m/^([-0-9a-z]+)((\s+.*)?)$/i ||
-                       $self->do_parse_error($file, $NR,
+                       $self->_do_parse_error($file, $NR,
                                              "badly formatted urgency value",
                                              $v);
                    $entry{'Urgency'} = $1;
@@ -198,7 +328,7 @@ sub parse {
                    # XC for putting in Control, XS for putting in Source
                    $entry{$k}= $v;
                } else {
-                   $self->do_parse_error($file, $NR,
+                   $self->_do_parse_error($file, $NR,
                                          "unknown key-value key $k - copying 
to XS-$k");
                    $entry{"XS-$k"} = $v;
                }
@@ -229,14 +359,14 @@ sub parse {
            $self->{oldformat} = "$_\n";
            $self->{oldformat} .= join "", <$fh>;
        } elsif (m/^\S/) {
-           $self->do_parse_error($file, $NR,
+           $self->_do_parse_error($file, $NR,
                                  "badly formatted heading line", "$_");
        } elsif (m/^ \-\- (.*) <(.*)>(  
?)((\w+\,\s*)?\d{1,2}\s+\w+\s+\d{4}\s+\d{1,2}:\d\d:\d\d\s+[-+]\d{4}(\s+\([^\\\(\)]\))?)$/o)
 {
            $expect eq 'more change data or trailer' ||
-               $self->do_parse_error($file, $NR,
+               $self->_do_parse_error($file, $NR,
                        "found trailer where expected $expect", "$_");
            if ($3 ne '  ') {
-               $self->do_parse_error($file, $NR,
+               $self->_do_parse_error($file, $NR,
                                      "badly formatted trailer line", "$_");
            }
            $entry{'Trailer'} = $_;
@@ -244,29 +374,25 @@ sub parse {
            unless($entry{'Date'} && $entry{'Parsed_Date'}) {
                $entry{'Date'} = $4;
                $entry{'Parsed_Date'} = str2time($4)
-                   or $self->do_parse_error( $file, $NR, "couldn't parse date 
$4" );
+                   or $self->_do_parse_error( $file, $NR, "couldn't parse date 
$4" );
            }
            $expect = 'next heading or eof';
        } elsif (m/^ \-\-/) {
            $entry{ERROR} = [ $file, $NR,
                              "badly formatted trailer line", "$_" ];
-           $self->do_parse_error(@{$entry{ERROR}});
+           $self->_do_parse_error(@{$entry{ERROR}});
 #          $expect = 'next heading or eof'
 #              if $expect eq 'more change data or trailer';
        } elsif (m/^\s{2,}(\S)/) {
            $expect eq 'start of change data'
                || $expect eq 'more change data or trailer'
                || do {
-                   $self->do_parse_error($file, $NR,
+                   $self->_do_parse_error($file, $NR,
                            "found change data where expected $expect", "$_");
                    if (($expect eq 'next heading or eof')
                        && %entry) {
                        # lets assume we have missed the actual header line
-                       my @closes;
-                       while ($entry{'Changes'} && ($entry{'Changes'} =~ 
/closes:\s*(?:bug)?\#?\s?\d+(?:,\s*(?:bug)?\#?\s?\d+)*/igo)) {
-                           push(@closes, $& =~ /\#?\s?(\d+)/g);
-                       }
-                       $entry{'Closes'} = [ sort { $a <=> $b } @closes ];
+                       $entry{'Closes'} = __find_closes( $entry{Changes} );
                        
 #                  print STDERR, Dumper(%entry);
                        push @{$self->{data}}, { %entry };
@@ -293,11 +419,11 @@ sub parse {
            next if $expect eq 'start of change data'
                || $expect eq 'next heading or eof';
            $expect eq 'more change data or trailer'
-               || $self->do_parse_error($file, $NR,
+               || $self->_do_parse_error($file, $NR,
                                         "found blank line where expected 
$expect");
            $blanklines++;
        } else {
-           $self->do_parse_error($file, $NR, "unrecognised line", "$_");
+           $self->_do_parse_error($file, $NR, "unrecognised line", "$_");
            ($expect eq 'start of change data'
                || $expect eq 'more change data or trailer')
                && do {
@@ -319,14 +445,10 @@ sub parse {
     $expect eq 'next heading or eof'
        || do {
            $entry{ERROR} = [ $file, $NR, "found eof where expected $expect" ];
-           $self->do_parse_error( @{$entry{ERROR}} );
+           $self->_do_parse_error( @{$entry{ERROR}} );
        };
     if (%entry) {
-       my @closes;
-       while ($entry{'Changes'} =~ 
/closes:\s*(?:bug)?\#?\s?\d+(?:,\s*(?:bug)?\#?\s?\d+)*/ig) {
-           push(@closes, $& =~ /\#?\s?(\d+)/g);
-       }
-       $entry{'Closes'} = join(' ', sort { $a <=> $b } @closes);
+       $entry{'Closes'} = __find_closes( $entry{Changes} );
        
        push @{$self->{data}}, \%entry;
     }
@@ -339,66 +461,270 @@ sub parse {
     return $self;
 }
 
-sub dpkg_out {
-    my ($self, $config) = @_;
 
-    $self->{config}{DPKG} = $config if $config;
+sub __data2rfc822_mult {
+    my ($data, $fieldimps) = @_;
+    my @rfc822 = ();
 
-    $config = $self->{config}{DPKG} || {};
-    my $data = $self->{data} or return undef;
-    my $since = $config->{since} || '';
+    foreach my $entry (@$data) {
+       push @rfc822, __data2rfc822($entry,$fieldimps);
+    }
 
-    my $dpkglibdir="/usr/lib/dpkg";
-    push @INC, $dpkglibdir;
-    require 'controllib.pl';
+    return join "\n", @rfc822;
+}
+
+sub __data2rfc822 {
+    my ($data, $fieldimps) = @_;
+    my $rfc822_str = '';
+
+# based on /usr/lib/dpkg/controllib.pl
+    for my $f (sort { $fieldimps->{$b} <=> $fieldimps->{$a} } keys %$data) {
+        my $v= $data->{$f};
+        $v =~ m/\S/o || next; # delete whitespace-only fields
+        $v =~ m/\n\S/o && warn("field $f has newline then non whitespace 
>$v<");
+        $v =~ m/\n[ \t]*\n/o && warn("field $f has blank lines >$v<");
+        $v =~ m/\n$/o && warn("field $f has trailing newline >$v<");
+        $v =~ s/\$\{\}/\$/go;
+        $rfc822_str .= "$f: $v\n";
+    }
 
-    our ( %fieldimps, %urgencies, %f );
+    return $rfc822_str;
+}
+
+sub __get_dpkg_changes {
+    my $changes = "\n $_[0]->{Header}\n .\n$_[0]->{Changes}";
+    chomp $changes;
+    $changes =~ s/^ $/ ./mgo;
+    return $changes;
+}
+
+our ( %FIELDIMPS, %URGENCIES );
+BEGIN {
     my $i=100;
-    grep($fieldimps{$_}=$i--,
+    grep($FIELDIMPS{$_}=$i--,
         qw(Source Version Distribution Urgency Maintainer Date Closes
            Changes));
     $i=1;
-    grep($urgencies{$_}=$i++,
+    grep($URGENCIES{$_}=$i++,
         qw(low medium high critical emergency));
+}
+
+=pod
+
+=head3 dpkg
+
+(and B<dpkg_str>)
+
+C<dpkg> returns a hash (in list context) or a hash reference
+(in scalar context) where the keys are field names and the values are
+field values. The following fields are given:
+
+=over 4
+
+=item Source
+
+package name (in the first entry)
+
+=item Version
+
+packages' version (from first entry)
+
+=item Distribution
+
+target distribution (from first entry)
+
+=item Urgency
+
+urgency (highest of all printed entries)
+
+=item Maintainer
+
+person that created the (first) entry
+
+=item Date
+
+date of the (first) entry
+
+=item Closes
+
+bugs closed by the entry/entries, sorted by bug number
+
+=item Changes
+
+content of the the entry/entries
+
+=back
 
+C<dpkg_str> returns a stringified version of this hash which should look
+exactly like the output of L<dpkg-parsechangelog(1)>. The fields are
+ordered like in the list above.
+
+Both methods support the configuration item C<since> which works exactly
+like the C<-v> option of dpkg-parsechangelog.
+
+=cut
+
+sub dpkg {
+    my ($self, $config) = @_;
+
+    $self->{config}{DPKG} = $config if $config;
+
+    $config = $self->{config}{DPKG} || {};
+    my $data = $self->{data} or return undef;
+    my $since = $config->{since} || '';
+
+    my %f;
     foreach my $field (qw( Urgency Source Version
                           Distribution Maintainer Date )) {
        $f{$field} = $data->[0]{$field};
     }
 
-    error( "-v<since> option specifies most recent version" )
+    warn( "-v<since> option specifies most recent version" )
        if $f{Version} eq $since;
 
-    $f{Changes} = "\n $data->[0]{Header}\n .\n$data->[0]{Changes}";
-    chomp $f{Changes};
-    $f{Closes} = "@{$data->[0]{Closes}}";
+    $f{Changes} = __get_dpkg_changes( $data->[0] );
+    $f{Closes} = [ @{$data->[0]{Closes}} ];
 
-    my $first = 1;
+    my $first = 1; my $urg_comment = '';
     foreach my $entry (@$data) {
        $first = 0, next if $first;
        last if !$since or $entry->{Version} eq $since;
 
        my $oldurg = $f{Urgency} || '';
-       my $oldurgn = $urgencies{$f{Urgency}} || -1;
+       my $oldurgn = $URGENCIES{$f{Urgency}} || -1;
        my $newurg = $entry->{Urgency_LC} || '';
-       my $newurgn = $urgencies{$entry->{Urgency_LC}} || -1;
+       my $newurgn = $URGENCIES{$entry->{Urgency_LC}} || -1;
        $f{Urgency} = ($newurgn > $oldurgn) ? $newurg : $oldurg;
-       $f{Urgency_Comment} .= $entry->{Urgency_Comment};
+       $urg_comment .= $entry->{Urgency_Comment};
        
-       $f{Changes} .= "\n .\n $entry->{Header}\n .\n$entry->{Changes}";
-       chomp $f{Changes};
-       $f{Closes} .= " @{$entry->{Closes}}";
+       $f{Changes} .= "\n .".__get_dpkg_changes( $entry );
+       push @{$f{Closes}}, @{$entry->{Closes}};
 
     }
 
-    $f{Changes} =~ s/^ $/ ./mgo;
-    $f{Urgency} .= $f{Urgency_Comment};
-    delete $f{Urgency_Comment};
+    $f{Closes} = join " ", sort { $a <=> $b } @{$f{Closes}};
+    $f{Urgency} .= $urg_comment;
+
+    return %f if wantarray;
+    return \%f;
+}
 
-    outputclose(0);
+sub dpkg_str {
+    return __data2rfc822( scalar dpkg(@_), \%FIELDIMPS );
 }
 
-sub html_out {
+=pod
+
+=head3 rfc822
+
+(and B<rfc822_str>)
+
+C<rfc822> returns an array of hashes (in list context) or a reference
+to this array (in scalar context) where each hash represents one entry
+in the changelog. For the format of such a hash see the description
+of the L<"dpkg"> method (while ignoring the remarks about which
+values are taken from the first entry).
+
+C<rfc822_str> returns a stringified version of this hash which looks
+similar to the output of dpkg-parsechangelog but instead of one
+stanza the output contains one stanza for each entry.
+
+Both methods support the configuration item C<since> which works exactly
+like the C<-v> option of dpkg-parsechangelog.
+
+=cut
+
+sub rfc822 {
+    my ($self, $config) = @_;
+
+    $self->{config}{RFC822} = $config if $config;
+
+    $config = $self->{config}{RFC822} || {};
+    my $data = $self->{data} or return undef;
+    my $since = $config->{since} || '';
+
+    my @out_data;
+    warn( "-v<since> option specifies most recent version" )
+       if $data->[0]{Version} eq $since;
+
+    my $first = 1;
+    foreach my $entry (@$data) {
+       last if (!$since and !$first) or $entry->{Version} eq $since;
+       $first = 0;
+
+       my %f;
+       foreach my $field (qw( Urgency Source Version
+                          Distribution Maintainer Date )) {
+           $f{$field} = $entry->{$field};
+       }
+
+       $f{Urgency} .= $entry->{Urgency_Comment};
+       $f{Changes} = __get_dpkg_changes( $entry );
+       $f{Closes} = join " ", sort { $a <=> $b } @{$entry->{Closes}};
+       push @out_data, \%f;
+    }
+
+    return @out_data if wantarray;
+    return \@out_data;
+}
+
+sub rfc822_str {
+    return __data2rfc822_mult( scalar rfc822(@_), \%FIELDIMPS );
+}
+
+sub __version2id {
+    my $version = shift;
+    $version =~ s/[^\w.:-]/_/go;
+    return "version$version";
+}
+
+=pod
+
+=head3 html
+
+(and B<html_str>)
+
+C<html> converts the changelog to a HTML file with some nice features
+such as a quicklink bar with direct links to every entry. The HTML
+is generated with the help of HTML::Template. If you want to change
+the output you should use the default template provided with this module
+as a base and read the documentation of HTML::Template to understand
+how to edit it.
+
+The method C<html_str> is an alias for C<html>.
+
+Both methods support the following configuration items (as usual to give
+in a hash reference as parameter to the method call):
+
+=over 4
+
+=item outfile
+
+directly write the output to the file specified
+
+=item template
+
+template file to use, defaults to
+/usr/share/libparse-debianchangelog-perl/default.tmpl.
+NOTE: The plan is to provide a configuration file for the module
+later to be able to use sane defaults here.
+
+=item style
+
+path to the CSS stylesheet to use (a default might be specified
+in the template and will be honoured, see the default template
+for an example)
+
+=item print_style
+
+path to the CSS stylesheet to use for printing (see the notes for
+C<style> about default values)
+
+=back
+
+=cut
+
+sub html {
     my ($self, $config) = @_;
     
     $self->{config}{HTML} = $config if $config;
@@ -409,52 +735,25 @@ sub html_out {
     import CGI qw( -no_xhtml -no_debug );
     require HTML::Entities;
     import HTML::Entities;
-    require URI::Escape;
-    import URI::Escape;
+    require HTML::Template;
+    
+    my $template = HTML::Template->new(filename => $config->{template}
+                                      || 
'/usr/share/libparse-debianchangelog-perl/default.tmpl');
+    $template->param( MODULE_NAME => $CLASSNAME,
+                     MODULE_VERSION => $VERSION,
+                     GENERATED_DATE => gmtime()." UTC",
+                     SOURCE_NEWEST => $data->[0]{Source},
+                     VERSION_NEWEST => $data->[0]{Version},
+                     MAINTAINER_NEWEST => $data->[0]{Maintainer},
+                     );
+
+    $template->param( CSS_FILE_SCREEN => $config->{style} )
+       if $config->{style};
+    $template->param( CSS_FILE_PRINT => $config->{print_style} )
+       if $config->{print_style};
 
-    my $outfile = $config->{outfile} or return undef;
     my $cgi = new CGI;
 
-    open my $fh, '>', $outfile or return undef;
-    flock $fh, LOCK_EX or return undef;
-
-    print $fh $cgi->start_html( -title => $config->{title}
-                               || "Debian Changelog $data->[0]{Source} 
($data->[0]{Version})",
-                               -author => $config->{author}
-                               || $data->[0]{Maintainer},
-                               -meta=>{ keywords => $config->{keywords}
-                                        || "Debian Changelog 
$data->[0]{Source} $data->[0]{Version}",
-                                        generator => "$CLASSNAME (v$VERSION)" 
},
-                               -head=>[ $cgi->meta({ -http_equiv => 
'Content-Type',
-                                                     -content => 'text/html; 
charset=UTF-8' }),
-                                        $cgi->Link({-rel=>'stylesheet',
-                                                    -href => $config->{style}
-                                                    || 'changelogs.css',
-                                                    -type => 'text/css',
-                                                    -media => 'screen' }),
-                                        $cgi->Link({-rel=>'stylesheet',
-                                                    -href => 
$config->{print_style}
-                                                    || 'changelogs-print.css',
-                                                    -type => 'text/css',
-                                                    -media => 'print' }),
-                                        ],
-                               );
-
-    print $fh $cgi->p({ -class=>'hide' },
-                     $cgi->a({ -href=>'#content' },
-                             'Skip to content' ));
-
-    print $fh $cgi->ul( { -class=>'navbar' },
-                       $cgi->li( [
-                                  $cgi->a({ 
-href=>"http://packages.debian.org/src:$data->[0]{Source}" }, 'Package 
Information' ),
-                                  $cgi->a({ 
-href=>"http://packages.qa.debian.org/$data->[0]{Source}" }, 'Package Developer 
Information' ),
-                                  $cgi->a({ 
-href=>"http://bugs.debian.org/src:$data->[0]{Source}" }, 'Bug Information' ),
-                                  ] ) );
-
-    print $fh $cgi->h1( { -class=>"document_header" },
-                       $config->{title}
-                       || "Debian Changelog $data->[0]{Source} 
($data->[0]{Version})" );
-
     my %navigation;
     my $last_year;
     foreach my $entry (@$data) {
@@ -463,27 +762,29 @@ sub html_out {
            $year = (gmtime($entry->{Parsed_Date}))[5] + 1900;
            $last_year = $year;
        }
-       
+
        $year ||= (($entry->{Date} =~ /\s(\d{4})\s/) ? $1 : (gmtime)[5] + 1900);
-       $navigation{$year} ||= [];
-       $entry->{Maintainer} ||= 'unkown';
-       $entry->{Date} ||= 'unkown';
-       push @{$navigation{$year}}, $cgi->a({-href=>"#version$entry->{Version}",
-                                            
-title=>encode_entities("$entry->{Maintainer} $entry->{Date}",'<>&"')},
-                                           $entry->{Version});
+
+       $navigation{$year}{NAV_VERSIONS} ||= [];
+       $navigation{$year}{NAV_YEAR} ||= $year;
+
+       $entry->{Maintainer} ||= 'unknown';
+       $entry->{Date} ||= 'unknown';
+       push @{$navigation{$year}{NAV_VERSIONS}},
+              { NAV_VERSION_ID => __version2id($entry->{Version}),
+                NAV_VERSION => $entry->{Version},
+                NAV_MAINTAINER => $entry->{Maintainer},
+                NAV_DATE => $entry->{Date} };
     }
-    print $fh $cgi->start_ul( { -class=>'outline' } );
+    my @nav_years;
     foreach my $y (reverse sort keys %navigation) {
-       print $fh $cgi->li(
-                          $cgi->a({ -href=>"#year$y" },$y).": ".
-                          $cgi->ul( $cgi->li( $navigation{$y} ) ) );
-    }
-    if ($self->{oldformat}) {
-       print $fh $cgi->li($cgi->a({ -href=>'#oldformat' }, 'old format'));
+       push @nav_years, $navigation{$y};
     }
-    print $fh $cgi->end_ul;
-       
-    print $fh $cgi->start_div({ -id=>'content'});
+    $template->param( OLDFORMAT => (($self->{oldformat}||'') ne ''),
+                     NAV_YEARS => \@nav_years );
+
+
+    my %years;
     $last_year = undef;
     foreach my $entry (@$data) {
        my $year = $last_year; # try to deal gracefully with unparsable dates
@@ -491,29 +792,15 @@ sub html_out {
            $year = (gmtime($entry->{Parsed_Date}))[5] + 1900;
        }
        $year ||= (($entry->{Date} =~ /\s(\d{4})\s/) ? $1 : (gmtime)[5] + 
1900);        
-
+       
        if (!$last_year || ($year < $last_year)) {
-           print $fh $cgi->h2( { -class=>'year_header',
-                                 -id=>"year$year" }, $year );
            $last_year = $year;
        }
 
-       my $pkg = $cgi->a({ -href=>"http://packages.debian.org/src:";.
-                               uri_escape($entry->{Source}),
-                           -class=>'packagelink' }, 
-                         $entry->{Source} );
-
-       print $fh $cgi->h3( { -class=>'entry_header',
-                             -id=>"version$entry->{Version}" },
-                           "$pkg ($entry->{Version}) ".
-                           $cgi->span( { -class=>$entry->{Distribution} },
-                                       $entry->{Distribution} ).
-                           "; urgency=".
-                           $cgi->span( { -class=>$entry->{Urgency_LC} },
-                                       $entry->{Urgency}.
-                                       $entry->{Urgency_Comment} ) );
-       
-       my $text = encode_entities( $entry->{Changes}, '<>&"' ) || "";
+       $years{$last_year}{CONTENT_VERSIONS} ||= [];
+       $years{$last_year}{CONTENT_YEAR} ||= $last_year;
+
+       my $text = encode_entities( $entry->{Changes}, '<>&"' ) || '';
        $text=~ s|&lt;URL:([-\w\.\/:~_\@]+):([a-zA-Z0-9\'() ]+)&gt;
                 |$cgi->a({ -href=>$1 }, $2)
                 |xego;
@@ -556,48 +843,61 @@ sub html_out {
                 |$cgi->a({ -href=>"http://www.debian.org/misc/bsd.license"; }, 
$&)
                 |xego;
 
-       print $fh $cgi->pre($text);
+       (my $maint_name = $entry->{Maintainer} ) =~ 
s|<([a-zA-Z0-9_\+\-\.]+\@([a-zA-Z0-9][\w\.+\-]+\.[a-zA-Z]{2,}))>||o;
+       my $maint_mail = $1;
+
+       my $parse_error;
+       $parse_error = $cgi->p( { -class=>'parse_error' },
+                               "(There has been a parse error in the entry 
above, if some values don't make sense please check the original changelog)" ) 
if $entry->{ERROR};
+       
+       push @{$years{$last_year}{CONTENT_VERSIONS}}, {
+           CONTENT_VERSION => $entry->{Version},
+           CONTENT_VERSION_ID => __version2id($entry->{Version}),
+           CONTENT_URGENCY => $entry->{Urgency}.$entry->{Urgency_Comment},
+           CONTENT_URGENCY_NORM => $entry->{Urgency_LC},
+           CONTENT_DISTRIBUTION => $entry->{Distribution},
+           CONTENT_DISTRIBUTION_NORM => lc($entry->{Distribution}),
+           CONTENT_SOURCE => $entry->{Source},
+           CONTENT_CHANGES => $text,
+           CONTENT_DATE => $entry->{Date},
+           CONTENT_MAINTAINER_NAME => $maint_name,
+           CONTENT_MAINTAINER_EMAIL => $maint_mail,
+           CONTENT_PARSE_ERROR => $parse_error,
+       };
+       
+    }
+    my @content_years;
+    foreach my $y (reverse sort keys %years) {
+       push @content_years, $years{$y};
+    }
+    $template->param( OLDFORMAT_CHANGES => $self->{oldformat},
+                     CONTENT_YEARS => \@content_years );
+
+    my $html_str = $template->output;
 
-       my $maint = encode_entities( $entry->{Maintainer}, '<>&"' );
-       $maint =~ s|[a-zA-Z0-9_\+\-\.]+\@([a-zA-Z0-9][\w\.+\-]+\.[a-zA-Z]{2,})
-                  |$cgi->a({ 
-href=>"http://qa.debian.org/developer.php?login=$&"; }, $&)
-                  |xego;
+    if ($config->{outfile}) {
+       open my $fh, '>', $config->{outfile} or return undef;
+       flock $fh, LOCK_EX or return undef;
 
-       print $fh $cgi->p( { -class=>'trailer' }, "  -- $maint $entry->{Date}" 
);
-       print $fh $cgi->p( { -class=>'parse_error' },
-                          "(There has been a parse error in the entry above, 
if some values don't make sense please check the original changelog)" ) if 
$entry->{ERROR};
+       print $fh $html_str;
 
+       close $fh or return undef;
     }
-    if ($self->{oldformat}) {
-       print $fh $cgi->h2({ -class=>'year_header', -id=>'oldformat' },
-                          'Old changelog format(s), not parsed' );
-       print $fh $cgi->pre({ -class=>'oldformat' },
-                           encode_entities( $self->{oldformat}, '<>&"' ) );
-    }
-    print $fh $cgi->end_div; # content
-    
-    print $fh $cgi->div({-class=>'footer'},
-                       $cgi->hr({-class=>'hide'}).
-                       $cgi->address(
-                                     'Generated '.
-                                     gmtime().
-                                     ' UTC by '.
-                                     $cgi->tt("$CLASSNAME (v$VERSION)").
-                                     $cgi->br().
-                                     'Contact '.
-                                     $cgi->a({ 
-href=>'mailto:debian-...@lists.debian.org' },
-                                             'debian-...@lists.debian.org' ).
-                                     ' in case of problems.'
-                                     ) );
-
-    print $fh $cgi->end_html;
-    close $fh or return undef;
 
-    return $self;
+    return $html_str;
+}
+
+sub html_str {
+    return html(@_);
 }
 
 1;
 __END__
+=head1 SEE ALSO
+
+Description of the Debian changelog format in the Debian policy:
+L<http://www.debian.org/doc/debian-policy/ch-source.html#s-dpkgchangelog>.
+
 =head1 AUTHOR
 
 Frank Lichtenheld, E<lt>fr...@lichtenheld.dee<gt>
diff --git a/t/Parse-DebianChangelog.t b/t/Parse-DebianChangelog.t
index 1a46d28..12c6791 100644
--- a/t/Parse-DebianChangelog.t
+++ b/t/Parse-DebianChangelog.t
@@ -1,3 +1,4 @@
+# -*- perl -*-
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl 
Parse-DebianChangelog.t'
 
@@ -5,12 +6,47 @@
 
 # change 'tests => 1' to 'tests => last_test_to_print';
 
-use Test::More tests => 2;
+use strict;
+use warnings;
+
+use File::Basename;
+
+use Test::More tests => 7;
 BEGIN { use_ok('Parse::DebianChangelog') };
 
 #########################
 
-my $changes = Parse::DebianChangelog->init( { infile => 'Changes' } );
-my $errors = $changes->get_parse_errors();
+foreach my $file (qw(Changes)) {
+
+    my $changes = Parse::DebianChangelog->init( { infile => $file } );
+    my $errors = $changes->get_parse_errors();
+    my $basename = basename( $file );
+    
+    ok( !$errors, "Parse example changelog $file without errors" );
+
+    $changes->html( { outfile => "t/$basename.html.tmp",
+                     template => 'tmpl/default.tmpl' } );
+
+    ok( !`tidy -qe t/$basename.html.tmp 2>&1`, 'Generated HTML has no tidy 
errors' );
+
+    unlink "t/$basename.html.tmp";
+
+    my $str = $changes->dpkg_str();
+
+    ok( $str eq `dpkg-parsechangelog -l$file 2>&1`, 'Output of dpkg_out equal 
to output of dpkg-parsechangelog' );
+
+    my $oldest_version = $changes->{data}[-1]{Version};
+
+    $str = $changes->dpkg_str({ since => $oldest_version });
+
+    ok( $str eq `dpkg-parsechangelog -v$oldest_version -l$file 2>&1`, 'Output 
of dpkg_out equal to output of dpkg-parsechangelog' );
+
+    $str = $changes->rfc822_str();
+
+    ok( 1 );
+
+    $str = $changes->rfc822_str({ since => $oldest_version });
+
+    ok( 1 );
+}
 
-ok( !$errors, 'Parse the own changelog without errors' );

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-perl/packages/libparse-debianchangelog-perl.git

_______________________________________________
Pkg-perl-cvs-commits mailing list
Pkg-perl-cvs-commits@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-perl-cvs-commits

Reply via email to