File Coverage

blib/lib/Pod/POM/View/HTML.pm
Criterion Covered Total %
statement 134 151 88.7
branch 33 60 55.0
condition 3 11 27.2
subroutine 30 31 96.7
pod 20 25 80.0
total 220 278 79.1


line stmt bran cond sub pod time code
1             #============================================================= -*-Perl-*-
2             #
3             # Pod::POM::View::HTML
4             #
5             # DESCRIPTION
6             # HTML view of a Pod Object Model.
7             #
8             # AUTHOR
9             # Andy Wardley
10             #
11             # COPYRIGHT
12             # Copyright (C) 2000 Andy Wardley. All Rights Reserved.
13             #
14             # This module is free software; you can redistribute it and/or
15             # modify it under the same terms as Perl itself.
16             #
17             # REVISION
18             # $Id: HTML.pm 84 2009-08-20 21:07:00Z ford $
19             #
20             #========================================================================
21              
22             package Pod::POM::View::HTML;
23             $Pod::POM::View::HTML::VERSION = '2.00';
24             require 5.006;
25              
26 5     5   10339 use strict;
  5         10  
  5         545  
27 5     5   66 use warnings;
  5         10  
  5         417  
28              
29 5     5   242 use Pod::POM::View;
  5         11  
  5         357  
30 5     5   37 use parent qw( Pod::POM::View );
  5         10  
  5         41  
31 5     5   1168 use vars qw( $DEBUG $ERROR $AUTOLOAD );
  5         10  
  5         962  
32 5     5   7678 use Text::Wrap;
  5         11968  
  5         12233  
33              
34             $DEBUG = 0 unless defined $DEBUG;
35             my $HTML_PROTECT = 0;
36             my @OVER;
37              
38             sub new {
39 0     0 1 0 my $class = shift;
40 0   0     0 my $self = $class->SUPER::new(@_)
41             || return;
42              
43             # initalise stack for maintaining info for nested lists
44 0         0 $self->{ OVER } = [];
45              
46 0         0 return $self;
47             }
48              
49              
50             sub view {
51 2     2 1 4 my ($self, $type, $item) = @_;
52              
53 2 50       8 if ($type =~ s/^seq_//) {
    0          
    0          
54 2         11 return $item;
55             }
56             elsif (UNIVERSAL::isa($item, 'HASH')) {
57 0 0       0 if (defined $item->{ content }) {
    0          
58 0         0 return $item->{ content }->present($self);
59             }
60             elsif (defined $item->{ text }) {
61 0         0 my $text = $item->{ text };
62 0 0       0 return ref $text ? $text->present($self) : $text;
63             }
64             else {
65 0         0 return '';
66             }
67             }
68             elsif (! ref $item) {
69 0         0 return $item;
70             }
71             else {
72 0         0 return '';
73             }
74             }
75              
76              
77             sub view_pod {
78 14     14 1 23 my ($self, $pod) = @_;
79 14         109 return "\n\n"
80             . $pod->content->present($self)
81             . "\n\n";
82             }
83              
84              
85             sub view_head1 {
86 32     32 1 48 my ($self, $head1) = @_;
87 32         149 my $title = $head1->title->present($self);
88 32         176 return "

$title

\n\n"
89             . $head1->content->present($self);
90             }
91              
92              
93             sub view_head2 {
94 8     8 1 12 my ($self, $head2) = @_;
95 8         43 my $title = $head2->title->present($self);
96 8         42 return "

$title

\n"
97             . $head2->content->present($self);
98             }
99              
100              
101             sub view_head3 {
102 5     5 1 7 my ($self, $head3) = @_;
103 5         24 my $title = $head3->title->present($self);
104 5         27 return "

$title

\n"
105             . $head3->content->present($self);
106             }
107              
108              
109             sub view_head4 {
110 7     7 1 11 my ($self, $head4) = @_;
111 7         30 my $title = $head4->title->present($self);
112 7         33 return "

$title

\n"
113             . $head4->content->present($self);
114             }
115              
116              
117             sub view_over {
118 14     14 1 26 my ($self, $over) = @_;
119 14         14 my ($start, $end, $strip);
120 14         75 my $items = $over->item();
121              
122 14 100       36 if (@$items) {
123              
124 11         62 my $first_title = $items->[0]->title();
125              
126 11 100       36 if ($first_title =~ /^\s*\*\s*/) {
    100          
127             # '=item *' =>
128 5         10 $start = "
    \n";
129 5         8 $end = "\n";
130 5         32 $strip = qr/^\s*\*\s*/;
131             }
132             elsif ($first_title =~ /^\s*\d+\.?\s*/) {
133             # '=item 1.' or '=item 1 ' =>
134 3         4 $start = "
    \n";
135 3         7 $end = "\n";
136 3         12 $strip = qr/^\s*\d+\.?\s*/;
137             }
138             else {
139 3         7 $start = "
    \n";
140 3         15 $end = "\n";
141 3         6 $strip = '';
142             }
143              
144 11 50       33 my $overstack = ref $self ? $self->{ OVER } : \@OVER;
145 11         19 push(@$overstack, $strip);
146 11         70 my $content = $over->content->present($self);
147 11         259 pop(@$overstack);
148            
149 11         48 return $start
150             . $content
151             . $end;
152             }
153             else {
154 3         15 return "
\n"
155             . $over->content->present($self)
156             . "\n";
157             }
158             }
159              
160              
161             sub view_item {
162 28     28 1 44 my ($self, $item) = @_;
163              
164 28 50       50 my $over = ref $self ? $self->{ OVER } : \@OVER;
165 28         113 my $title = $item->title();
166 28         50 my $strip = $over->[-1];
167              
168 28 50       58 if (defined $title) {
169 28 100       101 $title = $title->present($self) if ref $title;
170 28 100       156 $title =~ s/$strip// if $strip;
171 28 100       65 if (length $title) {
172 14         20 my $anchor = $title;
173 14         84 $anchor =~ s/^\s*|\s*$//g; # strip leading and closing spaces
174 14         43 $anchor =~ s/\W/_/g;
175 14         43 $title = qq{$title};
176             }
177             }
178              
179 28         146 return '
  • '
  • 180             . "$title\n"
    181             . $item->content->present($self)
    182             . "\n";
    183             }
    184              
    185              
    186             sub view_for {
    187 1     1 1 2 my ($self, $for) = @_;
    188 1 50       11 return '' unless $for->format() =~ /\bhtml\b/;
    189 1         7 return $for->text()
    190             . "\n\n";
    191             }
    192            
    193              
    194             sub view_begin {
    195 4     4 1 8 my ($self, $begin) = @_;
    196 4 100       29 return '' unless $begin->format() =~ /\bhtml\b/;
    197 2         5 $HTML_PROTECT++;
    198 2         27 my $output = $begin->content->present($self);
    199 2         4 $HTML_PROTECT--;
    200 2         7 return $output;
    201             }
    202            
    203              
    204             sub view_textblock {
    205 94     94 1 132 my ($self, $text) = @_;
    206 94 100       512 return $HTML_PROTECT ? "$text\n" : "

    $text

    \n";
    207             }
    208              
    209              
    210             sub view_verbatim {
    211 6     6 1 10 my ($self, $text) = @_;
    212 6         11 for ($text) {
    213 6         11 s/&/&/g;
    214 6         18 s/
    215 6         14 s/>/>/g;
    216             }
    217 6         35 return "
    $text
    \n\n";
    218             }
    219              
    220              
    221             sub view_seq_bold {
    222 11     11 1 16 my ($self, $text) = @_;
    223 11         46 return "$text";
    224             }
    225              
    226              
    227             sub view_seq_italic {
    228 11     11 1 16 my ($self, $text) = @_;
    229 11         49 return "$text";
    230             }
    231              
    232              
    233             sub view_seq_code {
    234 10     10 1 18 my ($self, $text) = @_;
    235 10         43 return "$text";
    236             }
    237              
    238             sub view_seq_file {
    239 4     4 1 8 my ($self, $text) = @_;
    240 4         21 return "$text";
    241             }
    242              
    243             sub view_seq_space {
    244 4     4 0 8 my ($self, $text) = @_;
    245 4         24 $text =~ s/\s/ /g;
    246 4         15 return $text;
    247             }
    248              
    249              
    250             sub view_seq_entity {
    251 14     14 1 24 my ($self, $entity) = @_;
    252 14         51 return "&$entity;"
    253             }
    254              
    255              
    256             sub view_seq_index {
    257 2     2 1 6 return '';
    258             }
    259              
    260              
    261             sub view_seq_link {
    262 3     3 1 5 my ($self, $link) = @_;
    263              
    264             # view_seq_text has already taken care of L
    265 3 50       9 if ($link =~ /^
    266 0         0 return $link;
    267             }
    268              
    269             # full-blown URL's are emitted as-is
    270 3 50       9 if ($link =~ m{^\w+://}s ) {
    271 0         0 return make_href($link);
    272             }
    273              
    274 3         11 $link =~ s/\n/ /g; # undo line-wrapped tags
    275              
    276 3         4 my $orig_link = $link;
    277 3         3 my $linktext;
    278             # strip the sub-title and the following '|' char
    279 3 100       12 if ( $link =~ s/^ ([^|]+) \| //x ) {
    280 1         3 $linktext = $1;
    281             }
    282              
    283             # make sure sections start with a /
    284 3         5 $link =~ s|^"|/"|;
    285              
    286 3         5 my $page;
    287             my $section;
    288 3 50       12 if ($link =~ m|^ (.*?) / "? (.*?) "? $|x) { # [name]/"section"
        50          
    289 0         0 ($page, $section) = ($1, $2);
    290             }
    291             elsif ($link =~ /\s/) { # this must be a section with missing quotes
    292 0         0 ($page, $section) = ('', $link);
    293             }
    294             else {
    295 3         5 ($page, $section) = ($link, '');
    296             }
    297              
    298             # warning; show some text.
    299 3 100       10 $linktext = $orig_link unless defined $linktext;
    300              
    301 3         4 my $url = '';
    302 3 50 33     19 if (defined $page && length $page) {
    303 3         9 $url = $self->view_seq_link_transform_path($page);
    304             }
    305              
    306             # append the #section if exists
    307 3 0 33     8 $url .= "#$section" if defined $url and
          33        
    308             defined $section and length $section;
    309              
    310 3         6 return make_href($url, $linktext);
    311             }
    312              
    313              
    314             # should be sub-classed if extra transformations are needed
    315             #
    316             # for example a sub-class may search for the given page and return a
    317             # relative path to it.
    318             #
    319             # META: where this functionality should be documented? This module
    320             # doesn't have docs section
    321             #
    322             sub view_seq_link_transform_path {
    323 3     3 0 3 my($self, $page) = @_;
    324              
    325             # right now the default transform doesn't check whether the link
    326             # is not dead (i.e. whether there is a corresponding file.
    327             # therefore we don't link L<>'s other than L
    328             # subclass to change the default (and of course add validation)
    329              
    330             # this is the minimal transformation that will be required if enabled
    331             # $page = "$page.html";
    332             # $page =~ s|::|/|g;
    333             #print "page $page\n";
    334 3         7 return undef;
    335             }
    336              
    337              
    338             sub make_href {
    339 3     3 0 7 my($url, $title) = @_;
    340              
    341 3 50       5 if (!defined $url) {
    342 3 50       18 return defined $title ? "$title" : '';
    343             }
    344              
    345 0 0       0 $title = $url unless defined $title;
    346             #print "$url, $title\n";
    347 0         0 return qq{$title};
    348             }
    349              
    350              
    351              
    352              
    353             # this code has been borrowed from Pod::Html
    354             my $urls = '(' . join ('|',
    355             qw{
    356             http
    357             telnet
    358             mailto
    359             news
    360             gopher
    361             file
    362             wais
    363             ftp
    364             } ) . ')';
    365             my $ltrs = '\w';
    366             my $gunk = '/#~:.?+=&%@!\-';
    367             my $punc = '.:!?\-;';
    368             my $any = "${ltrs}${gunk}${punc}";
    369              
    370             sub view_seq_text {
    371 295     295 0 396 my ($self, $text) = @_;
    372              
    373 295 50       524 unless ($HTML_PROTECT) {
    374 295         442 for ($text) {
    375 295         375 s/&/&/g;
    376 295         386 s/
    377 295         503 s/>/>/g;
    378             }
    379             }
    380              
    381 295         1200 $text =~ s{
    382             \b # start at word boundary
    383             ( # begin $1 {
    384             $urls : # need resource and a colon
    385             (?!:) # Ignore File::, among others.
    386             [$any] +? # followed by one or more of any valid
    387             # character, but be conservative and
    388             # take only what you need to....
    389             ) # end $1 }
    390             (?= # look-ahead non-consumptive assertion
    391             [$punc]* # either 0 or more punctuation followed
    392             (?: # followed
    393             [^$any] # by a non-url char
    394             | # or
    395             $ # end of the string
    396             ) #
    397             | # or else
    398             $ # then end of the string
    399             )
    400             }{$1}igox;
    401              
    402 295         1185 return $text;
    403             }
    404              
    405             sub encode {
    406 113     113 0 151 my($self,$text) = @_;
    407 113         2255 require Encode;
    408 113         19951 return Encode::encode("ascii",$text,Encode::FB_XMLCREF());
    409             }
    410              
    411             1;
    412              
    413             =head1 NAME
    414              
    415             Pod::POM::View::HTML
    416              
    417             =head1 DESCRIPTION
    418              
    419             HTML view of a Pod Object Model.
    420              
    421             =head1 METHODS
    422              
    423             =over 4
    424              
    425             =item C
    426              
    427             =item C
    428              
    429             =item C
    430              
    431             =item C
    432              
    433             =item C
    434              
    435             =item C
    436              
    437             =item C
    438              
    439             =item C
    440              
    441             =item C
    442              
    443             =item C
    444              
    445             =item C
    446              
    447             =item C
    448              
    449             =item C
    450              
    451             =item C
    452              
    453             Returns the text of a CE> sequence enclosed in a Cb> element.
    454              
    455             =item C
    456              
    457             Returns the text of a CE> sequence enclosed in a Ci> element.
    458              
    459             =item C
    460              
    461             Returns the text of a CE> sequence enclosed in a Ccode> element.
    462              
    463             =item C
    464              
    465             =item C
    466              
    467             =item C
    468              
    469             Returns an empty string. Index sequences are suppressed in HTML view.
    470              
    471             =item C
    472              
    473             =back
    474              
    475             =head1 AUTHOR
    476              
    477             Andy Wardley Eabw@kfs.orgE
    478              
    479             =head1 COPYRIGHT AND LICENSE
    480              
    481             Copyright (C) 2000 Andy Wardley. All Rights Reserved.
    482              
    483             This module is free software; you can redistribute it and/or
    484             modify it under the same terms as Perl itself.
    485              
    486             =cut