| blib/lib/HTML/TagCloud.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % |
| statement | 104 | 127 | 81.8 |
| branch | 26 | 36 | 72.2 |
| condition | 2 | 6 | 33.3 |
| subroutine | 16 | 19 | 84.2 |
| pod | 9 | 9 | 100.0 |
| total | 157 | 197 | 79.7 |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package HTML::TagCloud; | ||||||
| 2 | 1 | 1 | 894 | use strict; | |||
| 1 | 3 | ||||||
| 1 | 45 | ||||||
| 3 | 1 | 1 | 6 | use warnings; | |||
| 1 | 3 | ||||||
| 1 | 71 | ||||||
| 4 | our $VERSION = '0.38'; | ||||||
| 5 | |||||||
| 6 | 1 | 1 | 6 | use constant EMPTY_STRING => q{}; | |||
| 1 | 2 | ||||||
| 1 | 1535 | ||||||
| 7 | |||||||
| 8 | sub new { | ||||||
| 9 | 9 | 9 | 1 | 5769 | my $class = shift; | ||
| 10 | 9 | 54 | my $self = { | ||||
| 11 | counts => {}, | ||||||
| 12 | urls => {}, | ||||||
| 13 | category_for => {}, | ||||||
| 14 | categories => [], | ||||||
| 15 | levels => 24, | ||||||
| 16 | distinguish_adjacent_tags => 0, | ||||||
| 17 | @_ | ||||||
| 18 | }; | ||||||
| 19 | 9 | 26 | bless $self, $class; | ||||
| 20 | 9 | 19 | return $self; | ||||
| 21 | } | ||||||
| 22 | |||||||
| 23 | sub add { | ||||||
| 24 | 359 | 359 | 1 | 2846 | my ( $self, $tag, $url, $count, $category ) = @_; | ||
| 25 | 359 | 572 | $self->{counts}->{$tag} = $count; | ||||
| 26 | 359 | 527 | $self->{urls}->{$tag} = $url; | ||||
| 27 | 359 | 50 | 33 | 305 | if ( scalar @{ $self->{categories} } > 0 && defined $category ) { | ||
| 359 | 987 | ||||||
| 28 | 0 | 0 | $self->{category_for}->{$tag} = $category; | ||||
| 29 | } | ||||||
| 30 | } | ||||||
| 31 | |||||||
| 32 | sub add_static { | ||||||
| 33 | 10 | 10 | 1 | 49 | my ( $self, $tag, $count, $category ) = @_; | ||
| 34 | 10 | 22 | $self->{counts}->{$tag} = $count; | ||||
| 35 | |||||||
| 36 | 10 | 50 | 33 | 10 | if ( scalar @{ $self->{categories} } > 0 && defined $category ) { | ||
| 10 | 43 | ||||||
| 37 | 0 | 0 | $self->{category_for}->{$tag} = $category; | ||||
| 38 | } | ||||||
| 39 | } | ||||||
| 40 | |||||||
| 41 | sub css { | ||||||
| 42 | 3 | 3 | 1 | 30 | my ($self) = @_; | ||
| 43 | 3 | 7 | my $css = q( | ||||
| 44 | #htmltagcloud { | ||||||
| 45 | text-align: center; | ||||||
| 46 | line-height: 1; | ||||||
| 47 | } | ||||||
| 48 | ); | ||||||
| 49 | 3 | 11 | foreach my $level ( 0 .. $self->{levels} ) { | ||||
| 50 | 75 | 100 | 137 | if ( $self->{distinguish_adjacent_tags} ) { | |||
| 51 | 25 | 43 | $css .= $self->_css_for_tag( $level, 'even' ); | ||||
| 52 | 25 | 42 | $css .= $self->_css_for_tag( $level, 'odd' ); | ||||
| 53 | } | ||||||
| 54 | else { | ||||||
| 55 | 50 | 78 | $css .= $self->_css_for_tag( $level, q{} ); | ||||
| 56 | } | ||||||
| 57 | } | ||||||
| 58 | 3 | 27 | return $css; | ||||
| 59 | } | ||||||
| 60 | |||||||
| 61 | sub _css_for_tag { | ||||||
| 62 | 100 | 100 | 127 | my ( $self, $level, $subclass ) = @_; | |||
| 63 | 100 | 113 | my $font = 12 + $level; | ||||
| 64 | 100 | 313 | return <<"END_OF_TAG"; | ||||
| 65 | span.tagcloud${level}${subclass} {font-size: ${font}px;} | ||||||
| 66 | span.tagcloud${level}${subclass} a {text-decoration: none;} | ||||||
| 67 | END_OF_TAG | ||||||
| 68 | } | ||||||
| 69 | |||||||
| 70 | sub tags { | ||||||
| 71 | 15 | 15 | 1 | 17 | my ( $self, $limit ) = @_; | ||
| 72 | 15 | 28 | my $counts = $self->{counts}; | ||||
| 73 | 15 | 21 | my $urls = $self->{urls}; | ||||
| 74 | 15 | 22 | my $category_for = $self->{category_for}; | ||||
| 75 | 15 | 50 | 309 | my @tags = sort { $counts->{$b} <=> $counts->{$a} || $a cmp $b } keys %$counts; | |||
| 17732 | 34295 | ||||||
| 76 | 15 | 100 | 205 | @tags = splice( @tags, 0, $limit ) if defined $limit; | |||
| 77 | |||||||
| 78 | 15 | 100 | 40 | return unless scalar @tags; | |||
| 79 | |||||||
| 80 | 14 | 62 | my $min = log( $counts->{ $tags[-1] } ); | ||||
| 81 | 14 | 30 | my $max = log( $counts->{ $tags[0] } ); | ||||
| 82 | 14 | 16 | my $factor; | ||||
| 83 | |||||||
| 84 | # special case all tags having the same count | ||||||
| 85 | 14 | 100 | 45 | if ( $max - $min == 0 ) { | |||
| 86 | 9 | 14 | $min = $min - $self->{levels}; | ||||
| 87 | 9 | 12 | $factor = 1; | ||||
| 88 | } | ||||||
| 89 | else { | ||||||
| 90 | 5 | 15 | $factor = $self->{levels} / ( $max - $min ); | ||||
| 91 | } | ||||||
| 92 | |||||||
| 93 | 14 | 100 | 36 | if ( scalar @tags < $self->{levels} ) { | |||
| 94 | 13 | 28 | $factor *= ( scalar @tags / $self->{levels} ); | ||||
| 95 | } | ||||||
| 96 | 14 | 18 | my @tag_items; | ||||
| 97 | 14 | 160 | foreach my $tag ( sort @tags ) { | ||||
| 98 | 402 | 358 | my $tag_item; | ||||
| 99 | 402 | 657 | $tag_item->{name} = $tag; | ||||
| 100 | 402 | 526 | $tag_item->{count} = $counts->{$tag}; | ||||
| 101 | 402 | 604 | $tag_item->{url} = $urls->{$tag}; | ||||
| 102 | 402 | 797 | $tag_item->{level} | ||||
| 103 | = int( ( log( $tag_item->{count} ) - $min ) * $factor ); | ||||||
| 104 | 402 | 476 | $tag_item->{category} = $category_for->{$tag}; | ||||
| 105 | 402 | 578 | push @tag_items, $tag_item; | ||||
| 106 | } | ||||||
| 107 | 14 | 168 | return @tag_items; | ||||
| 108 | } | ||||||
| 109 | |||||||
| 110 | sub html { | ||||||
| 111 | 15 | 15 | 1 | 4902 | my ( $self, $limit ) = @_; | ||
| 112 | 15 | 60 | my $html | ||||
| 113 | 15 | 50 | 17 | = scalar @{ $self->{categories} } > 0 | |||
| 114 | ? $self->html_with_categories($limit) | ||||||
| 115 | : $self->html_without_categories($limit); | ||||||
| 116 | 15 | 257 | return $html; | ||||
| 117 | } | ||||||
| 118 | |||||||
| 119 | sub html_without_categories { | ||||||
| 120 | 15 | 15 | 1 | 20 | my ( $self, $limit ) = @_; | ||
| 121 | 15 | 31 | my $html = $self->_html_for( [ $self->tags($limit) ] ); | ||||
| 122 | } | ||||||
| 123 | |||||||
| 124 | sub _html_for { | ||||||
| 125 | 15 | 15 | 21 | my ( $self, $tags_ref ) = @_; | |||
| 126 | 15 | 22 | my $ntags = scalar( @{$tags_ref} ); | ||||
| 15 | 19 | ||||||
| 127 | 15 | 100 | 43 | return EMPTY_STRING if $ntags == 0; | |||
| 128 | |||||||
| 129 | # Format the HTML division. | ||||||
| 130 | 14 | 100 | 72 | my $html | |||
| 131 | = $ntags == 1 | ||||||
| 132 | ? $self->_html_for_single_tag($tags_ref) | ||||||
| 133 | : $self->_html_for_multiple_tags($tags_ref); | ||||||
| 134 | |||||||
| 135 | 14 | 38 | return $html; | ||||
| 136 | } | ||||||
| 137 | |||||||
| 138 | sub _html_for_single_tag { | ||||||
| 139 | 3 | 3 | 6 | my ( $self, $tags_ref ) = @_; | |||
| 140 | |||||||
| 141 | # Format the contents of the div. | ||||||
| 142 | 3 | 4 | my $tag_ref = $tags_ref->[0]; | ||||
| 143 | 3 | 7 | my $html = $self->_format_span( @{$tag_ref}{qw(name url)}, 1, 1 ); | ||||
| 3 | 12 | ||||||
| 144 | |||||||
| 145 | 3 | 10 | return qq{ $html \n}; |
||||
| 146 | } | ||||||
| 147 | |||||||
| 148 | sub _html_for_multiple_tags { | ||||||
| 149 | 11 | 11 | 17 | my ( $self, $tags_ref ) = @_; | |||
| 150 | |||||||
| 151 | # Format the contents of the div. | ||||||
| 152 | 11 | 16 | my $html = EMPTY_STRING; | ||||
| 153 | 11 | 12 | my $is_even = 1; | ||||
| 154 | 11 | 24 | foreach my $tag ( @{$tags_ref} ) { | ||||
| 11 | 20 | ||||||
| 155 | 399 | 1030 | my $span | ||||
| 156 | 399 | 429 | = $self->_format_span( @{$tag}{qw(name url level)}, $is_even ); | ||||
| 157 | 399 | 788 | $html .= "$span\n"; | ||||
| 158 | 399 | 574 | $is_even = !$is_even; | ||||
| 159 | } | ||||||
| 160 | 11 | 66 | $html = qq{ |
||||
| 161 | $html}; | ||||||
| 162 | 11 | 56 | return $html; | ||||
| 163 | } | ||||||
| 164 | |||||||
| 165 | sub html_with_categories { | ||||||
| 166 | 0 | 0 | 1 | 0 | my ( $self, $limit ) = @_; | ||
| 167 | |||||||
| 168 | # Get the collection of tags, organized by category. | ||||||
| 169 | 0 | 0 | my $tags_by_category_ref = $self->_tags_by_category($limit); | ||||
| 170 | 0 | 0 | 0 | return EMPTY_STRING if !defined $tags_by_category_ref; | |||
| 171 | |||||||
| 172 | # Format the HTML document. | ||||||
| 173 | 0 | 0 | my $html = EMPTY_STRING; | ||||
| 174 | 0 | 0 | CATEGORY: | ||||
| 175 | 0 | 0 | for my $category ( @{ $self->{categories} } ) { | ||||
| 176 | 0 | 0 | my $tags_ref = $tags_by_category_ref->{$category}; | ||||
| 177 | 0 | 0 | $html .= $self->_html_for_category( $category, $tags_ref ); | ||||
| 178 | } | ||||||
| 179 | |||||||
| 180 | 0 | 0 | return $html; | ||||
| 181 | } | ||||||
| 182 | |||||||
| 183 | sub _html_for_category { | ||||||
| 184 | 0 | 0 | 0 | my ( $self, $category, $tags_ref ) = @_; | |||
| 185 | |||||||
| 186 | # Format the HTML. | ||||||
| 187 | 0 | 0 | my $html | ||||
| 188 | = qq{ } |
||||||
| 189 | . $self->_html_for($tags_ref) | ||||||
| 190 | . qq{}; | ||||||
| 191 | |||||||
| 192 | 0 | 0 | return $html; | ||||
| 193 | } | ||||||
| 194 | |||||||
| 195 | sub _tags_by_category { | ||||||
| 196 | 0 | 0 | 0 | my ( $self, $limit ) = @_; | |||
| 197 | |||||||
| 198 | # Get the tags. | ||||||
| 199 | 0 | 0 | my @tags = $self->tags($limit); | ||||
| 200 | 0 | 0 | 0 | return if scalar @tags == 0; | |||
| 201 | |||||||
| 202 | # Build the categorized collection of tags. | ||||||
| 203 | 0 | 0 | my %tags_by_category; | ||||
| 204 | 0 | 0 | for my $tag_ref (@tags) { | ||||
| 205 | 0 | 0 | 0 | my $category | |||
| 206 | = defined $tag_ref->{category} | ||||||
| 207 | ? $tag_ref->{category} | ||||||
| 208 | : '__unknown__'; | ||||||
| 209 | 0 | 0 | push @{ $tags_by_category{$category} }, $tag_ref; | ||||
| 0 | 0 | ||||||
| 210 | } | ||||||
| 211 | |||||||
| 212 | 0 | 0 | return \%tags_by_category; | ||||
| 213 | } | ||||||
| 214 | |||||||
| 215 | sub html_and_css { | ||||||
| 216 | 1 | 1 | 1 | 1233 | my ( $self, $limit ) = @_; | ||
| 217 | 1 | 6 | my $html = qq{"; | ||||
| 218 | 1 | 3 | $html .= $self->html($limit); | ||||
| 219 | 1 | 8 | return $html; | ||||
| 220 | } | ||||||
| 221 | |||||||
| 222 | sub _format_span { | ||||||
| 223 | 402 | 402 | 613 | my ( $self, $name, $url, $level, $is_even ) = @_; | |||
| 224 | 402 | 469 | my $subclass = q{}; | ||||
| 225 | 402 | 100 | 783 | if ( $self->{distinguish_adjacent_tags} ) { | |||
| 226 | 10 | 100 | 22 | $subclass = $is_even ? 'even' : 'odd'; | |||
| 227 | } | ||||||
| 228 | 402 | 610 | my $span_class = qq{tagcloud$level$subclass}; | ||||
| 229 | 402 | 1597 | my $span = qq{}; | ||||
| 230 | 402 | 100 | 770 | if ( defined $url ) { | |||
| 231 | 392 | 705 | $span .= qq{}; | ||||
| 232 | } | ||||||
| 233 | 402 | 447 | $span .= $name; | ||||
| 234 | 402 | 100 | 687 | if ( defined $url ) { | |||
| 235 | 392 | 438 | $span .= qq{}; | ||||
| 236 | } | ||||||
| 237 | 402 | 803 | $span .= qq{}; | ||||
| 238 | } | ||||||
| 239 | |||||||
| 240 | 1; | ||||||
| 241 | |||||||
| 242 | __END__ |