File Coverage

blib/lib/HTML/FromMail.pm
Criterion Covered Total %
statement 21 109 19.2
branch 0 60 0.0
condition 0 14 0.0
subroutine 7 14 50.0
pod 6 7 85.7
total 34 204 16.6


line stmt bran cond sub pod time code
1             # This code is part of Perl distribution HTML-FromMail version 4.00.
2             # The POD got stripped from this file by OODoc version 3.05.
3             # For contributors see file ChangeLog.
4              
5             # This software is copyright (c) 2003-2025 by Mark Overmeer.
6              
7             # This is free software; you can redistribute it and/or modify it under
8             # the same terms as the Perl 5 programming language system itself.
9             # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later
10              
11              
12             package HTML::FromMail;{
13             our $VERSION = '4.00';
14             }
15              
16 1     1   2065 use base 'Mail::Reporter';
  1         2  
  1         155  
17              
18 1     1   9 use strict;
  1         19  
  1         40  
19 1     1   6 use warnings;
  1         3  
  1         72  
20              
21 1     1   8 use Log::Report 'html-frommail';
  1         2  
  1         9  
22              
23 1     1   436 use File::Spec::Functions qw/catfile catdir file_name_is_absolute/;
  1         2  
  1         131  
24 1     1   7 use File::Basename qw/basename dirname/;
  1         2  
  1         775  
25              
26             my %default_producers = ( # classes will be compiled automatically when used
27             'Mail::Message' => 'HTML::FromMail::Message',
28             'Mail::Message::Head' => 'HTML::FromMail::Head',
29             'Mail::Message::Field' => 'HTML::FromMail::Field',
30             );
31              
32             #--------------------
33              
34             sub init($)
35 0     0 0   { my ($self, $args) = @_;
36 0           $self->SUPER::init($args);
37              
38             # Defining the formatter to be used
39 0   0       my $form = $args->{formatter} || {};
40 0 0         if(!ref $form)
    0          
41 0           { eval "require $form";
42 0 0         $@ and panic "Formatter $form can not be used:\n$@";
43 0           $form = $form->new;
44             }
45             elsif(ref $form eq 'HASH')
46 0           { require HTML::FromMail::Format::OODoc;
47 0           $form = HTML::FromMail::Format::OODoc->new(%$form);
48             }
49              
50 0 0         defined $form
51             or error __x"formatter {class} could not be instantiated.", class => $form;
52              
53 0           $self->{HF_formatter} = $form;
54              
55             # Defining the producers
56 0           my %prod = %default_producers; # copy
57 0   0       my $prod = $args->{producers} || {};
58 0           @prod{ keys %$prod } = values %$prod;
59 0           while( my($class, $impl) = each %prod)
60 0           { $self->producer($class, $impl);
61             }
62              
63             # Collect the settings
64 0   0       my $settings = $args->{settings} || {};
65 0           while( my ($topic, $defaults) = each %$settings)
66 0           { $self->settings($topic, $defaults);
67             }
68              
69 0   0       $self->{HF_templates} = $args->{templates} || '.';
70 0           $self;
71             }
72              
73             #--------------------
74              
75 0     0 1   sub formatter() { $_[0]->{HF_formatter} }
76              
77             #-----------
78              
79              
80             sub producer($;$)
81 0     0 1   { my ($self, $thing) = (shift, shift);
82 0   0       my $class = ref $thing || $thing;
83              
84 0 0         return ($self->{HF_producer}{$class} = shift) if @_;
85 0 0         if(my $prod = $self->{HF_producer}{$class})
86 0           { eval "require $prod";
87 0 0         $@ and error __x"cannot use {producer} for {class}:\n$@", producer => $prod, class => $class, error => $@;
88 0           return $prod->new;
89             }
90              
91             # Look for producer in the inheritance structure
92 1     1   11 no strict 'refs';
  1         2  
  1         1356  
93 0           foreach ( @{"$class\::ISA"} )
  0            
94 0           { my $prod = $self->producer($_);
95 0 0         return $prod if defined $prod;
96             }
97              
98 0           undef;
99             }
100              
101              
102             sub templates(;$)
103 0     0 1   { my $self = shift;
104 0 0         return $self->{HF_templates} unless @_;
105              
106 0 0         my $topic = blessed $_[0] ? shift->topic : shift;
107 0           my $templates= $self->{HF_templates};
108              
109 0           my $filename = catfile $templates, $topic;
110 0 0         return $filename if -f $filename;
111              
112 0           my $dirname = catdir $templates, $topic;
113 0 0         return $dirname if -d $dirname;
114              
115 0           error __x"cannot find template file or directory '{topic}' in '{directory}'.",
116             topic => $topic, directory => $templates;
117             }
118              
119              
120             sub settings($;@)
121 0     0 1   { my $self = shift;
122 0 0         my $topic = blessed $_[0] ? shift->topic : shift;
123 0 0         @_ or return $self->{HF_settings}{$topic};
124              
125 0 0         $self->{HF_settings}{$topic} = @_ == 1 ? shift : +{ @_ };
126             }
127              
128              
129             sub export($@)
130 0     0 1   { my ($self, $object, %args) = @_;
131              
132 0 0         my $producer = $self->producer($object)
133             or error __x"no producer for {class} objects.", class => ref $object;
134              
135             my $output = $args{output}
136 0 0         or error __x"no output directory or file specified.";
137              
138             # this cannot be right when $output isa filename?
139             # $self->log(ERROR => "Cannot create output directory $output: $!"), return
140             # unless -d $output || mkdir $output;
141              
142 0           my $topic = $producer->topic;
143 0           my @files;
144 0 0         if(my $input = $args{use})
145             { # some template files are explicitly named
146 0           my $templates = $self->templates;
147              
148 0 0         foreach my $in (ref $input ? @$input : $input)
149 0 0         { my $fn = file_name_is_absolute($in) ? $in : catfile($templates, $in);
150 0 0         -f $fn or warning(__x"no template file {file}.", file => $fn), next;
151              
152 0           push @files, $fn;
153             }
154             }
155             else
156 0 0         { my $templates = $self->templates($topic)
157             or warning(__x"no templates for {topic} objects.", topic => $topic), return;
158              
159 0           @files = $self->expandFiles($templates);
160 0 0         @files or warning __x"no templates found in {dir} directory.", dir => $templates;
161             }
162              
163 0           my $formatter = $self->formatter(settings => $self->{HF_settings});
164 0           my @outfiles;
165              
166 0           foreach my $infile (@files)
167 0           { my $basename = basename $infile;
168 0           my $outfile = catfile $output, $basename;
169 0           push @outfiles, $outfile;
170              
171 0           $formatter->export(
172             %args,
173             object => $object, input => $infile,
174             producer => $producer, formatter => $formatter,
175             output => $outfile, outdir => $output,
176             main => $self,
177             );
178             }
179              
180 0           $outfiles[0];
181             }
182              
183              
184             sub expandFiles($)
185 0     0 1   { my ($self, $thing) = @_;
186 0 0         return @$thing if ref $thing eq 'ARRAY';
187 0 0         return $thing if -f $thing;
188              
189 0 0         -d $thing
190             or warning(__x"cannot find directory {dir}.", dir => $thing), return ();
191              
192 0 0         opendir DIR, $thing
193             or fault __x"cannot read from directory {dir}", dir => $thing;
194              
195 0           my @files;
196 0           while(my $item = readdir DIR)
197 0 0 0       { next if $item eq '.' || $item eq '..';
198              
199 0           my $full = catfile $thing, $item;
200 0 0         if(-f $full)
201 0           { push @files, $full;
202 0           next;
203             }
204              
205 0           $full = catdir $thing, $item;
206 0 0         if(-d $full)
207 0           { push @files, $self->expandFiles($full);
208 0           next;
209             }
210              
211 0           warning __x"skipping {name}, which is neither file or directory.", name => $full;
212             }
213              
214 0           closedir DIR;
215 0           @files;
216             }
217              
218             #--------------------
219              
220             1;