File Coverage

blib/lib/Pod/Pandoc/Modules.pm
Criterion Covered Total %
statement 29 89 32.5
branch 0 32 0.0
condition 0 25 0.0
subroutine 10 17 58.8
pod 3 5 60.0
total 42 168 25.0


line stmt bran cond sub pod time code
1             package Pod::Pandoc::Modules;
2 7     7   53 use strict;
  7         19  
  7         230  
3 7     7   46 use warnings;
  7         16  
  7         205  
4 7     7   133 use 5.010;
  7         29  
5              
6             our $VERSION = '0.30';
7              
8 7     7   94 use File::Path qw(make_path);
  7         18  
  7         449  
9 7     7   51 use File::Find;
  7         22  
  7         472  
10 7     7   51 use File::Spec;
  7         16  
  7         191  
11 7     7   3407 use File::stat;
  7         50571  
  7         39  
12 7     7   514 use File::Basename qw(dirname);
  7         20  
  7         388  
13 7     7   54 use Pandoc::Elements;
  7         16  
  7         1831  
14 7     7   70 use Carp qw(croak);
  7         16  
  7         8388  
15              
16             sub new {
17 0   0 0 0   bless( ( $_[1] // {} ), $_[0] );
18             }
19              
20             sub add {
21 0     0 1   my ( $self, $name, $doc ) = @_;
22              
23 0 0         if ( my $given = $self->{$name} ) {
24 0 0         return if $doc->metavalue('file') !~ /\.pod/;
25             }
26 0   0       $doc->meta->{title} //= MetaString $name;
27              
28 0           $self->{$name} = $doc;
29             }
30              
31             sub module_link {
32 0     0 0   my ( $module, $opt ) = @_;
33              
34 0           my $target = $module;
35 0 0         if ( $opt->{subdirectories} ) { # TODO: document and test
36 0           $target =~ s{::}{/}g;
37             }
38             else {
39 0           $target =~ s{::}{-}g;
40             }
41              
42 0 0         if ( $opt->{wiki} ) {
43 0           return Link attributes {}, [ Str $module ], [ $target, 'wikilink' ];
44             }
45             else {
46 0   0       $target .= '.' . ( $opt->{ext} // 'html' );
47 0           return Link attributes {}, [ Str $module ], [ $target, $module ];
48             }
49             }
50              
51             sub index {
52 0     0 1   my ( $modules, %opt ) = @_;
53              
54             # TODO: extend, document, and test metadata
55 0           my %meta = map { $_ => MetaString "" . $opt{$_} }
56 0           grep { defined $opt{$_} } qw{title};
  0            
57              
58             my @definitions = map {
59 0           [
60             [ module_link( $_, \%opt ) ],
61             [
62             [
63 0   0       Plain [ Str( $modules->{$_}->metavalue('subtitle') // '' ) ]
64             ]
65             ]
66             ]
67             } sort keys %$modules;
68              
69 0           Document \%meta, [ DefinitionList \@definitions ];
70             }
71              
72             sub serialize {
73 0     0 1   my ( $modules, $dir, $opt, @args ) = _parse_arguments(@_);
74              
75             # adjust links
76             # TODO: create copy instead of transforming, so
77             # this can be called multiple times!
78 0           foreach my $doc ( values %$modules ) {
79             $doc->transform(
80             Link => sub {
81              
82             # TODO: use configured prefix instead of hard-coded URL base
83 0     0     my ( $module, $hash ) =
84             $_->url =~ qr{^https://metacpan\.org/pod/([^#]+)(#.*)?$};
85 0 0 0       return unless ( $module and $modules->{$module} );
86              
87             # TODO: check whether hash link target exists
88 0           my $link = module_link( $module, $opt );
89 0 0         if ( defined $hash ) {
90 0           $link->url( $link->url . $hash );
91             }
92 0           return $link;
93             }
94 0           );
95             }
96              
97             # serialize
98 0           foreach my $doc ( values %$modules ) {
99 0           my $file = $doc->metavalue('file');
100 0           my $module = $doc->metavalue('title');
101              
102 0           my $name = $module;
103 0 0         if ( $opt->{subdirectories} ) {
104 0           $name =~ s{::}{/}g;
105             }
106             else {
107 0           $name =~ s{::}{-}g;
108             }
109 0   0       $name .= '.' . ( $opt->{ext} // 'html' );
110 0           my $target = File::Spec->catfile( $dir, $name );
111              
112 0 0 0       if ( $opt->{update} and -e $target ) {
113 0 0         next if stat($file)->[9] <= stat($target)->[9];
114             }
115              
116 0           make_path( dirname($target) );
117 0           $doc->to_pandoc( -o => $target, @args );
118 0 0         say "$file => $target" unless $opt->{quiet};
119             }
120              
121             # create index file
122 0 0         if ( $opt->{index} ) {
123 0           my $index = $modules->index(%$opt);
124             my $target =
125 0           File::Spec->catfile( $dir, $opt->{index} . '.' . $opt->{ext} );
126 0           $index->to_pandoc( @args, -o => $target );
127 0 0         say $target unless $opt->{quiet};
128             }
129             }
130              
131             sub _parse_arguments {
132 0     0     my $modules = shift;
133              
134 0 0         my $dir = ref $_[0] ? undef : shift;
135 0 0         my %opt = ref $_[0] ? %{ shift() } : ();
  0            
136              
137 0   0       $dir //= $opt{dir} // croak "output directory must be specified!";
      0        
138 0 0         $opt{index} = 'index' unless exists $opt{index};
139              
140 0   0       $opt{ext} //= 'html';
141 0           $opt{ext} =~ s/^\.//;
142 0 0         croak "ext must not be .pm or .pod" if $opt{ext} =~ /^(pod|pm)$/;
143              
144 0           ( $modules, $dir, \%opt, @_ );
145             }
146              
147             1;
148             __END__