| blib/lib/HTML/ForumCode.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % |
| statement | 69 | 71 | 97.1 |
| branch | 6 | 8 | 75.0 |
| condition | 1 | 3 | 33.3 |
| subroutine | 18 | 18 | 100.0 |
| pod | 3 | 3 | 100.0 |
| total | 97 | 103 | 94.1 |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package HTML::ForumCode; | ||||||
| 2 | # vim: ts=8 sts=4 et sw=4 sr sta | ||||||
| 3 | 3 | 3 | 38811 | use strict; | |||
| 3 | 7 | ||||||
| 3 | 114 | ||||||
| 4 | 3 | 3 | 17 | use warnings; | |||
| 3 | 4 | ||||||
| 3 | 98 | ||||||
| 5 | |||||||
| 6 | 3 | 3 | 906 | use version; our $VERSION = qv('0.0.5')->numify; | |||
| 3 | 2717 | ||||||
| 3 | 19 | ||||||
| 7 | |||||||
| 8 | 3 | 3 | 1277 | use Template::Plugin::HTML; | |||
| 3 | 23662 | ||||||
| 3 | 5725 | ||||||
| 9 | |||||||
| 10 | sub new { | ||||||
| 11 | 1 | 1 | 1 | 14 | my ($class, @args) = @_; | ||
| 12 | |||||||
| 13 | 1 | 33 | 9 | my $new_obj = bless {}, (ref($class)||$class); | |||
| 14 | 1 | 6 | $new_obj->init; | ||||
| 15 | |||||||
| 16 | 1 | 3 | return $new_obj; | ||||
| 17 | } | ||||||
| 18 | |||||||
| 19 | sub init { | ||||||
| 20 | 2 | 2 | 1 | 6 | my $self = shift; | ||
| 21 | |||||||
| 22 | # simple [x][/x] --> |
||||||
| 23 | 2 | 24 | $self->{simple_tags} = [qw{ | ||||
| 24 | b | ||||||
| 25 | u | ||||||
| 26 | i | ||||||
| 27 | }]; | ||||||
| 28 | # replacements; e.g. __x__ --> x | ||||||
| 29 | 2 | 16 | $self->{replacements} = [ | ||||
| 30 | { from => '__', to => 'u' }, | ||||||
| 31 | { from => '\*\*', to => 'b' }, | ||||||
| 32 | ]; | ||||||
| 33 | |||||||
| 34 | 2 | 6 | return; | ||||
| 35 | } | ||||||
| 36 | |||||||
| 37 | sub forumcode { | ||||||
| 38 | 86 | 86 | 1 | 87248 | my ($self, $text) = @_; | ||
| 39 | |||||||
| 40 | # if we don't have any text, we don't have to do any work | ||||||
| 41 | 86 | 50 | 230 | if (not defined $text) { | |||
| 42 | 0 | 0 | return q{}; | ||||
| 43 | } | ||||||
| 44 | |||||||
| 45 | # first of all ESCAPE EVERYTHING! | ||||||
| 46 | 86 | 318 | $text = Template::Plugin::HTML->escape($text); | ||||
| 47 | |||||||
| 48 | # turn newlines into tags |
||||||
| 49 | 86 | 1039 | $self->_preserve_newlines(\$text ); | ||||
| 50 | |||||||
| 51 | 86 | 180 | $self->_simple_tags ( \$text ); | ||||
| 52 | 86 | 249 | $self->_replacements ( \$text ); | ||||
| 53 | 86 | 279 | $self->_colouring ( \$text ); | ||||
| 54 | 86 | 201 | $self->_lists ( \$text ); | ||||
| 55 | 86 | 181 | $self->_url_links ( \$text ); | ||||
| 56 | 86 | 204 | $self->_images ( \$text ); | ||||
| 57 | 86 | 206 | $self->_styled_block ( \$text ); | ||||
| 58 | 86 | 162 | $self->_quoted_block ( \$text ); | ||||
| 59 | |||||||
| 60 | 86 | 361 | return $text; | ||||
| 61 | } | ||||||
| 62 | |||||||
| 63 | sub _preserve_newlines { | ||||||
| 64 | 86 | 86 | 126 | my ($self, $textref) = @_; | |||
| 65 | |||||||
| 66 | 86 | 198 | $$textref =~ s{\n}{ }xmsg; |
||||
| 67 | } | ||||||
| 68 | |||||||
| 69 | sub _simple_tags { | ||||||
| 70 | 86 | 86 | 109 | my ($self, $textref) = @_; | |||
| 71 | |||||||
| 72 | # deal with acceptable [x]...[/x] markup | ||||||
| 73 | 86 | 117 | foreach my $tag (@{ $self->{simple_tags} }) { | ||||
| 86 | 199 | ||||||
| 74 | # we should be able to combine these two into one | ||||||
| 75 | #$$textref =~ s{\[$tag\]}{<$tag>}g; | ||||||
| 76 | #$$textref =~ s{\[/$tag\]}{$tag>}g; | ||||||
| 77 | 258 | 5236 | $$textref =~ s{ | ||||
| 78 | \[($tag)\] | ||||||
| 79 | (.+?) | ||||||
| 80 | \[/$tag\] | ||||||
| 81 | } | ||||||
| 82 | {<$1>$2$1>}xmsg; | ||||||
| 83 | } | ||||||
| 84 | } | ||||||
| 85 | |||||||
| 86 | sub _replacements { | ||||||
| 87 | 86 | 86 | 108 | my ($self, $textref) = @_; | |||
| 88 | |||||||
| 89 | # now deal with replacements | ||||||
| 90 | 86 | 99 | foreach my $tag (@{ $self->{replacements} }) { | ||||
| 86 | 178 | ||||||
| 91 | 172 | 2491 | $$textref =~ s{ | ||||
| 92 | $tag->{from} | ||||||
| 93 | (.+?) | ||||||
| 94 | $tag->{from} | ||||||
| 95 | } | ||||||
| 96 | {<$tag->{to}>$1$tag->{to}>}gx; | ||||||
| 97 | } | ||||||
| 98 | } | ||||||
| 99 | |||||||
| 100 | sub _url_links { | ||||||
| 101 | 86 | 86 | 106 | my ($self, $textref) = @_; | |||
| 102 | |||||||
| 103 | # deal with links with no text-label | ||||||
| 104 | 86 | 139 | $$textref =~ s{\[url\](.+?)\[/url\]} | ||||
| 105 | {$1}xmsg; | ||||||
| 106 | # deal with links with a text-label | ||||||
| 107 | 86 | 190 | $$textref =~ s{ | ||||
| 108 | \[url # start of url tag | ||||||
| 109 | \s+ # need some whitespace | ||||||
| 110 | name=" # name=" | ||||||
| 111 | (.+?) # the name | ||||||
| 112 | " # closing " | ||||||
| 113 | \s* # optional whitespace | ||||||
| 114 | \] # close the opening tag | ||||||
| 115 | (.+?) # the url | ||||||
| 116 | \[/url\] # close the URL tag | ||||||
| 117 | } | ||||||
| 118 | {$1}xmsg; | ||||||
| 119 | # bbcode / explosm style urls | ||||||
| 120 | 86 | 209 | $$textref =~ s{ | ||||
| 121 | \[URL=" # opening url tag | ||||||
| 122 | (.+?) # the url | ||||||
| 123 | "\] # close-opening tag | ||||||
| 124 | (.+?) # link name/text/label | ||||||
| 125 | \[/URL] # closing tag | ||||||
| 126 | } | ||||||
| 127 | {$2}ximsg; | ||||||
| 128 | } | ||||||
| 129 | |||||||
| 130 | sub _images { | ||||||
| 131 | 86 | 86 | 107 | my ($self, $textref) = @_; | |||
| 132 | |||||||
| 133 | # deal with image tags | ||||||
| 134 | 86 | 220 | $$textref =~ s{ | ||||
| 135 | \[img # opening img tag | ||||||
| 136 | (.*?) # optional parameters | ||||||
| 137 | \] # close-opening tag | ||||||
| 138 | (.+?) # image URL | ||||||
| 139 | \[/img\] # closing img tag | ||||||
| 140 | } | ||||||
| 141 | #{ |
||||||
| 142 | 20 | 48 | {&_image_tag_with_attr($2,$1)}ximsge; | ||||
| 143 | } | ||||||
| 144 | |||||||
| 145 | sub _image_tag_with_attr { | ||||||
| 146 | 20 | 20 | 59 | my ($uri, $attr_match) = @_; | |||
| 147 | |||||||
| 148 | # no annoying image attributes to worry about | ||||||
| 149 | 20 | 100 | 165 | if (q{} eq $attr_match) { | |||
| 150 | 10 | 58 | return qq{ |
||||
| 151 | } | ||||||
| 152 | # deal with annoying image attributes | ||||||
| 153 | else { | ||||||
| 154 | 10 | 67 | $attr_match =~ s{ | ||||
| 155 | (\w+) | ||||||
| 156 | = | ||||||
| 157 | " | ||||||
| 158 | (\w+?) | ||||||
| 159 | " | ||||||
| 160 | } | ||||||
| 161 | {$1="$2"}xmsg; | ||||||
| 162 | 10 | 49 | return qq{ |
||||
| 163 | } | ||||||
| 164 | } | ||||||
| 165 | |||||||
| 166 | sub _colouring { | ||||||
| 167 | 86 | 86 | 122 | my ($self, $textref) = @_; | |||
| 168 | |||||||
| 169 | # deal with colouring | ||||||
| 170 | 86 | 414 | $$textref =~ s{ | ||||
| 171 | \[(colou?r) | ||||||
| 172 | = | ||||||
| 173 | ( | ||||||
| 174 | red | orange | yellow | green | blue | ||||||
| 175 | | black | white | ||||||
| 176 | | \#[0-9a-fA-F]{3} | ||||||
| 177 | | \#[0-9a-fA-F]{6} | ||||||
| 178 | ) | ||||||
| 179 | \] | ||||||
| 180 | (.+?) | ||||||
| 181 | \[/\1\] | ||||||
| 182 | } | ||||||
| 183 | {$3}ixmsg; | ||||||
| 184 | } | ||||||
| 185 | |||||||
| 186 | sub _lists { | ||||||
| 187 | 86 | 86 | 106 | my ($self, $textref) = @_; | |||
| 188 | |||||||
| 189 | 86 | 212 | $$textref =~ s{ | ||||
| 190 | \[list\] | ||||||
| 191 | (?: | ||||||
| 192 | \s* | ||||||
| 193 | (?: | ||||||
| 194 | |
||||||
| 195 | )? | ||||||
| 196 | \s* | ||||||
| 197 | ) | ||||||
| 198 | (.+?) | ||||||
| 199 | \[/list\] | ||||||
| 200 | [\s]* | ||||||
| 201 | (?: | ||||||
| 202 | |
||||||
| 203 | )? | ||||||
| 204 | } | ||||||
| 205 | 4 | 11 | {_list_elements($1)}xmsge; | ||||
| 206 | } | ||||||
| 207 | |||||||
| 208 | sub _list_elements { | ||||||
| 209 | 4 | 4 | 10 | my ($text) = @_; | |||
| 210 | |||||||
| 211 | # ordered lists | ||||||
| 212 | 4 | 100 | 43 | if ( | |||
| 213 | $text =~ s{ | ||||||
| 214 | \[\*\] | ||||||
| 215 | \s* | ||||||
| 216 | (.+?) | ||||||
| 217 | |
||||||
| 218 | \s* | ||||||
| 219 | } | ||||||
| 220 | { |
||||||
| 221 | ) { | ||||||
| 222 | 2 | 9 | return qq{
|
||||
| 223 | } | ||||||
| 224 | |||||||
| 225 | # ordered lists | ||||||
| 226 | 2 | 50 | 36 | if ( | |||
| 227 | $text =~ s{ | ||||||
| 228 | \[1\] | ||||||
| 229 | \s* | ||||||
| 230 | (.+?) | ||||||
| 231 | |
||||||
| 232 | \s* | ||||||
| 233 | } | ||||||
| 234 | { |
||||||
| 235 | ) { | ||||||
| 236 | 2 | 11 | return qq{
|
||||
| 237 | } | ||||||
| 238 | |||||||
| 239 | |||||||
| 240 | # otherwise, just return what we were given | ||||||
| 241 | 0 | 0 | return $text; | ||||
| 242 | } | ||||||
| 243 | |||||||
| 244 | sub _styled_block { | ||||||
| 245 | 86 | 86 | 97 | my ($self, $textref) = @_; | |||
| 246 | |||||||
| 247 | 86 | 174 | $$textref =~ s{ | ||||
| 248 | \[(code|pre|quote)\] | ||||||
| 249 | (.+?) | ||||||
| 250 | \[/\1\] | ||||||
| 251 | } | ||||||
| 252 | { $2 }xmsg; |
||||||
| 253 | } | ||||||
| 254 | |||||||
| 255 | # this deals with the extended case of [quote] where we have the quoting= | ||||||
| 256 | # attribute | ||||||
| 257 | sub _quoted_block { | ||||||
| 258 | 86 | 86 | 132 | my ($self, $textref) = @_; | |||
| 259 | |||||||
| 260 | 86 | 153 | $$textref =~ s{ | ||||
| 261 | \[ | ||||||
| 262 | (quote) | ||||||
| 263 | \s+ | ||||||
| 264 | quoting= | ||||||
| 265 | " | ||||||
| 266 | (.+?) | ||||||
| 267 | " | ||||||
| 268 | \] | ||||||
| 269 | (.+?) | ||||||
| 270 | \[/\1\] | ||||||
| 271 | } | ||||||
| 272 | { Quoting $2: $3 |
||||||
| 273 | } | ||||||
| 274 | |||||||
| 275 | 1; | ||||||
| 276 | __END__ |