File Coverage

blib/lib/Pod/HTML_Elements.pm
Criterion Covered Total %
statement 161 217 74.1
branch 55 106 51.8
condition 12 20 60.0
subroutine 26 29 89.6
pod 0 20 0.0
total 254 392 64.8


line stmt bran cond sub pod time code
1             package Pod::HTML_Elements;
2 1     1   10039 use strict;
  1         3  
  1         52  
3 1     1   7 use Pod::Parser 1.061;
  1         37  
  1         56  
4 1     1   717 use Pod::Links qw(link_parse);
  1         3  
  1         61  
5 1     1   11278 use HTML::Element;
  1         31140  
  1         8  
6 1     1   50 use HTML::Entities;
  1         3  
  1         79  
7 1     1   876 use HTML::AsSubs qw(h1 a li title);
  1         5410  
  1         190  
8 1     1   11 use vars qw(@ISA $VERSION);
  1         2  
  1         81  
9             $VERSION = '0.08';
10 1     1   5 use base qw(Pod::Parser);
  1         2  
  1         100  
11 1     1   1257 use Data::Dumper;
  1         12056  
  1         3154  
12              
13             my $nbsp;
14              
15             sub begin_pod
16             {
17 1     1 0 1044 my $obj = shift;
18 1         12 delete $obj->{'title'};
19 1         12 my $html = HTML::Element->new('html');
20 1         41 my $head = HTML::Element->new('head');
21 1         18 my $body = HTML::Element->new('body');
22 1         20 $html->push_content($head);
23 1         20 $html->push_content($body);
24 1         11 $obj->{'html'} = $html;
25 1         3 $obj->{'body'} = $body;
26 1         2 $obj->{'current'} = $body;
27 1         2 $obj->{'head'} = $head;
28 1 50 33     195 if (defined $obj->{'Index'} and not defined $obj->{'index'})
29             {
30 0         0 $obj->{'index'} = HTML::Element->new('ul');
31             }
32             }
33              
34             sub current
35             {
36 73     73 0 82 my $obj = shift;
37 73 100       176 $obj->{'current'} = shift if (@_);
38 73         909 return $obj->{'current'};
39             }
40              
41 9     9 0 29 sub body { return shift->{'body'} }
42 1     1 0 44 sub head { return shift->{'head'} }
43 1     1 0 4 sub html { return shift->{'html'} }
44              
45             sub make_elem
46             {
47 60     60 0 77 my $tag = shift;
48 60         59 my $attributes;
49 60 100 66     539 if (@_ and defined $_[0] and ref($_[0]) eq "HASH")
      100        
50             {
51 1         3 $attributes = shift;
52             }
53             else
54             {
55 59         87 $attributes = {};
56             }
57 60         262 my $elem = new HTML::Element $tag, %$attributes;
58 60         13058 $elem->push_content(@_);
59 60         1000 return $elem;
60             }
61              
62             sub add_elem
63             {
64 36     36 0 80 my $body = shift->current;
65 36         78 my $elem = make_elem(@_);
66 36         92 $body->push_content($elem);
67 36         1616 return $elem;
68             }
69              
70             sub do_name
71             {
72 1     1 0 2 my ($parser,$t) = @_;
73 1         14 $t =~ s/(^\s+|\s+$)//g;
74 1         12 $parser->{'title'} = $t;
75 1         2 $parser->{'in_name'} = 0;
76 1         6 $parser->head->push_content(title($t));
77 1         58 my $i = $parser->{'index'};
78 1 50       6 if (defined $i)
79             {
80 0         0 my $links = $parser->{'Links'};
81 0 0       0 my $l = $links->relative_url($parser->{'Index'},$parser->output_file) if (defined $links);
82 0         0 $i->push_content("\n",li(a({href => $l},$t)));
83             }
84             }
85              
86             sub verbatim
87             {
88 4     4 0 56 my ($parser, $paragraph, $line_num) = @_;
89 4 50       16 $parser->do_name($paragraph) if ($parser->{'in_name'});
90 4         9 $parser->add_elem(pre => $paragraph);
91             }
92              
93             sub raw_text
94             {
95 25     25 0 44 my $text = '';
96 25         28 foreach (@{$_[0]})
  25         52  
97             {
98 26 100       102 $text .= (ref $_) ? raw_text($_->content) : $_;
99             }
100 25         60 return $text;
101             }
102              
103             sub textblock
104             {
105 4     4 0 6 my ($parser, $paragraph, $line_num) = @_;
106 4         11 my @expansion = $parser->parse_to_elem($paragraph, $line_num);
107 4 100       19 if ($parser->{'in_name'})
108             {
109 1         4 my $t = raw_text(\@expansion);
110 1         5 $parser->do_name($t);
111             }
112 4         11 my $c = $parser->current;
113 4 50       17 if ($c->tag eq 'dt')
114             {
115 0         0 $parser->current($c = $c->parent);
116 0         0 $parser->current($parser->add_elem('dd' => @expansion));
117             }
118             else
119             {
120 4         42 $parser->add_elem(p => @expansion);
121             }
122             }
123              
124             sub linktext
125             {
126 17     17 0 58 my $parser = shift;
127 17         28 my $links = $parser->{'Links'};
128 17 50       43 return $links->relative_url($parser->output_file,$links->url(@_)) if (defined $links);
129 17         28 return undef;
130             }
131              
132             sub non_break
133             {
134 0     0 0 0 my $tree = shift;
135 0         0 foreach ($tree->children)
136             {
137 0 0       0 if (ref $_)
138             {
139 0         0 non_break($_->parse_tree);
140             }
141             else
142             {
143 0         0 s/ /$nbsp/g;
144             }
145             }
146             }
147              
148             my %seq = (B => 'b', I => 'i', C => 'code', 'F' => 'i', 'L' => 'a');
149             sub seq_to_element
150             {
151 18     18 0 35 my ($parser, $cmd, $tree) = @_;
152 18         35 my $t = $seq{$cmd};
153 18 100       38 if ($t)
154             {
155 11         35 my @args = walk_tree($parser,$tree);
156 11 100       27 if ($cmd eq 'L')
157             {
158 2         5 my $txt = raw_text(\@args);
159 2         9 my ($text,@where) = link_parse($txt);
160 2 50       7 @args = ($text) if ($text ne $txt);
161 2 50       8 my $link = @where == 1 ? $where[0] : $parser->linktext(@where);
162 2 50       8 unshift(@args, { href => $link } ) if defined $link;
163             }
164 11         24 return make_elem($t,@args);
165             }
166 7 100       17 if ($cmd eq 'E')
167             {
168             # Assume only one simple string in the argument ...
169 6         15 my @args = walk_tree($parser,$tree);
170 6         24 my $s = raw_text(\@args);
171 6 100       86 return chr($s) if $s =~ /^\d+$/;
172 4         45 return decode_entities("&$s;");
173             }
174 1 50       6 return '' if ($cmd eq 'Z');
175 0 0       0 if ($cmd eq 'S')
176             {
177 0 0       0 $nbsp = decode_entities(' ') unless defined $nbsp;
178 0         0 non_break($tree);
179 0         0 return walk_tree($parser,$tree);
180             }
181 0         0 return ("$cmd<",walk_tree($parser,$tree),'>');
182             }
183              
184             sub walk_tree
185             {
186 48     48 0 62 my ($parser,$tree) = @_;
187 48         64 my @list = ();
188 48         208 foreach my $seq ($tree->children)
189             {
190 72 100       133 if (ref($seq))
191             {
192 18         92 my $cmd = $seq->cmd_name;
193 18         65 my $tree = $seq->parse_tree;
194 18         53 push(@list,seq_to_element($parser,$cmd,$tree));
195             }
196             else
197             {
198 54         126 push(@list,$seq);
199             }
200             }
201 48         690 return @list;
202             }
203              
204             sub parse_to_elem
205             {
206 31     31 0 43 my ($self,$text,$line_num) = @_;
207 31         2445 my $tree = $self->parse_text($text, $line_num);
208 31         77 return walk_tree($self,$tree);
209             }
210              
211              
212             sub command
213             {
214 27     27 0 378 my ($parser, $command, $paragraph, $line_num) = @_;
215 27         69 my @expansion = $parser->parse_to_elem($paragraph, $line_num);
216 27 100       127 if ($command =~ /^head(\d+)?$/)
    100          
    100          
    50          
    0          
    0          
    0          
    0          
217             {
218 9   50     36 my $rank = $1 || 3;
219 9         27 $parser->current($parser->body);
220 9         20 my $t = raw_text(\@expansion);
221 9         45 $t =~ s/\s+$//;
222 9 100 66     34 if ($t eq 'NAME' && !$parser->{'title'})
223             {
224 1         2 $parser->{in_name} = 1;
225             }
226 9         21 my $name = $parser->linktext($t);
227 9 50       19 if ($name)
228             {
229 0 0       0 @expansion = make_elem('a',{ name => substr($name,1) } , @expansion ) if (defined $name);
230             }
231 9 100       20 if ($rank == 1)
232             {
233 3 100 66     30 if ($parser->{'last_head1'} && $parser->{'last_head1'} eq $parser->input_file)
234             {
235 2         5 $parser->add_elem("p");
236 2         5 $parser->add_elem("hr");
237             }
238 3         14 $parser->{'last_head1'} = $parser->input_file;
239             }
240 9         33 $parser->add_elem("h$rank" => @expansion);
241             }
242             elsif ($command eq 'over')
243             {
244 6         17 $parser->current($parser->add_elem('ul'));
245             }
246             elsif ($command eq 'item')
247             {
248 6         8 my $expansion = shift(@expansion);
249 6         16 my $c = $parser->current;
250 6 50       21 unless ($c->tag =~ /^(ul|dl|ol|dd|dt)/)
251             {
252 0         0 my $file = $parser->input_file;
253 0         0 $parser->add_elem("h3" => $expansion, @expansion);
254 0         0 return;
255             }
256 6 50 33     124 if ($expansion =~ /^\*\s+(.*)$/)
    50          
257             {
258 0         0 $parser->add_elem(li => "$1",@expansion);
259             }
260             elsif ($expansion =~ /^\d+(?:\.|\s+|\))(.*)$/ ||
261             $expansion =~ /^\[\d+\](?:\.|\s+|\))(.*)$/
262             )
263             {
264 0         0 my $s = $1;
265 0 0       0 $c->tag('ol') unless $c->tag eq 'ol';
266 0         0 $parser->add_elem(li => $s,@expansion);
267             }
268             else
269             {
270 6 50       19 if ($c->tag eq 'dt')
271             {
272 0         0 my $e = make_elem('strong', $expansion, @expansion);
273 0         0 $parser->add_elem('br' => $e);
274             }
275             else
276             {
277 6 50       54 if ($c->tag eq 'dd')
278             {
279 0         0 $parser->current($c = $c->parent)
280             }
281 6 50       60 $c->tag('dl') unless $c->tag eq 'dl';
282 6         98 my $e = make_elem('strong', make_elem('p'), $expansion, @expansion);
283 6         37 my $t = raw_text([$expansion]);
284 6 50       22 if (length $t)
285             {
286 6         15 my $name = $parser->linktext($t);
287 6 50       16 $e = make_elem('a',{ name => substr($name,1) } , $e ) if (defined $name);
288             }
289 6         14 $parser->current($parser->add_elem(dt => $e));
290             }
291             }
292             }
293             elsif ($command eq 'back')
294             {
295 6         28 my $c = $parser->current;
296 6 50       20 $parser->current($c = $c->parent) if ($c->tag eq 'dd');
297 6 50       56 if ($c->tag =~ /^(ul|ol|dl)/)
298             {
299 0         0 $parser->current($c->parent);
300             }
301             }
302             elsif ($command eq 'pod')
303             {
304              
305             }
306             elsif ($command eq 'for')
307             {
308 0         0 my $f = $parser->input_file;
309 0         0 my $t = raw_text(\@expansion);
310             # warn "$f:for $t\n";
311 0         0 my $c = $parser->current;
312             }
313             elsif ($command eq 'begin')
314             {
315 0         0 my $f = $parser->input_file;
316 0         0 my $t = raw_text(\@expansion);
317 0         0 warn "$f:begin $t\n";
318 0         0 my $c = $parser->current;
319             }
320             elsif ($command eq 'end')
321             {
322 0         0 my $t = raw_text(\@expansion);
323 0         0 my $c = $parser->current;
324             }
325             else
326             {
327 0         0 warn "$command not implemented\n";
328 0         0 $parser->add_elem(p => "=$command ",@expansion);
329             }
330             }
331              
332             sub end_pod
333             {
334 1     1 0 3 my $parser = shift;
335              
336 1         5 $parser->add_elem("p");
337 1         3 $parser->add_elem("hr");
338 1 50       4 unless ($parser->{'NoDate'})
339             {
340 1         68 $parser->add_elem("i", make_elem( font => { size => "-1" } ,
341             "Last updated: ",scalar localtime));
342             }
343 1         6 my $html = $parser->html;
344 1 50       6 if ($html)
345             {
346 1         21 my $fh = $parser->output_handle;
347 1 50       5 if ($fh)
348             {
349 1 50       5 if ($parser->{'PostScript'})
    0          
350             {
351 1         1159 require HTML::FormatPS;
352 1         48308 my $formatter = new HTML::FormatPS
353             FontFamily => 'Times',
354             HorizontalMargin => HTML::FormatPS::mm(15),
355             VerticalMargin => HTML::FormatPS::mm(20),
356             PaperSize => 'A4';
357 1         301 print $fh $formatter->format($html);
358             }
359             elsif ($parser->{'Dump'})
360             {
361 0         0 $Data::Dumper::Indent = 1;
362 0         0 print $fh Dumper($html);
363             }
364             else
365             {
366 0         0 print $fh $html->as_HTML;
367             }
368             }
369 1         55911 $html->delete;
370             }
371             }
372              
373             sub write_index
374             {
375 0     0 0   my $parser = shift;
376 0           my $ifile = $parser->{'Index'};
377 0 0         if (defined $ifile)
378             {
379 0 0         if (open(my $fh,">$ifile"))
380             {
381 0           my $html = HTML::Element->new('html');
382 0           my $head = HTML::Element->new('head');
383 0           my $body = HTML::Element->new('body');
384 0           $html->push_content($head);
385 0           $html->push_content($body);
386 0           $body->push_content("\n",h1('Table of Contents'),$parser->{'index'},"\n");
387 0           print $fh $html->as_HTML;
388 0           $html->delete;
389 0           close($fh);
390             }
391             }
392             }
393              
394             sub interior_sequence
395             {
396 0     0 0   die "Should not be called now";
397             }
398              
399             1;
400             __END__