| blib/lib/HTML/BBReverse.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % |
| statement | 189 | 220 | 85.9 |
| branch | 84 | 136 | 61.7 |
| condition | 68 | 126 | 53.9 |
| subroutine | 10 | 10 | 100.0 |
| pod | 3 | 3 | 100.0 |
| total | 354 | 495 | 71.5 |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package HTML::BBReverse; | ||||||
| 2 | |||||||
| 3 | 1 | 1 | 25652 | use strict; | |||
| 1 | 2 | ||||||
| 1 | 42 | ||||||
| 4 | 1 | 1 | 6 | use warnings; | |||
| 1 | 1 | ||||||
| 1 | 32 | ||||||
| 5 | 1 | 1 | 6 | use vars qw($VERSION); | |||
| 1 | 7 | ||||||
| 1 | 3258 | ||||||
| 6 | $VERSION = "0.07"; | ||||||
| 7 | |||||||
| 8 | sub new { | ||||||
| 9 | 1 | 1 | 1 | 10 | my $self = shift; | ||
| 10 | 1 | 33 | 7 | my $class = ref($self) || $self; | |||
| 11 | 1 | 2 | my %args; | ||||
| 12 | 1 | 50 | 5 | $#_ % 2 ? %args = @_ : warn "Odd argument list at " . __PACKAGE__ . "::new"; | |||
| 13 | |||||||
| 14 | 1 | 8 | my %options = ( | ||||
| 15 | allowed_tags => [ qw( b i u code url size color img quote list email html ) ], | ||||||
| 16 | reverse_for_edit => 1, | ||||||
| 17 | in_paragraph => 0, | ||||||
| 18 | no_jslink => 1, | ||||||
| 19 | ); | ||||||
| 20 | 1 | 7 | return bless { %options, %args}, $class; | ||||
| 21 | } | ||||||
| 22 | |||||||
| 23 | |||||||
| 24 | sub parse { | ||||||
| 25 | 25 | 25 | 1 | 11928 | my $self = shift; | ||
| 26 | 25 | 35 | local $_ = shift; | ||||
| 27 | |||||||
| 28 | 25 | 100 | 56 | (return '') if !$_; | |||
| 29 | 24 | 27 | my %alwd; | ||||
| 30 | 24 | 23 | foreach my $tag (@{$self->{allowed_tags}}) { $alwd{$tag} = 1 } | ||||
| 24 | 50 | ||||||
| 288 | 429 | ||||||
| 31 | |||||||
| 32 | 24 | 45 | s/\&/\&\;/g; | ||||
| 33 | 24 | 30 | s/\<\;/g; | ||||
| 34 | 24 | 31 | s/>/\>\;/g; | ||||
| 35 | 24 | 40 | s/\r?\n/ \n/g; |
||||
| 36 | # first convert the code, list and html-tags, which can't be parsed with a simple regular expression | ||||||
| 37 | 24 | 0 | 33 | 105 | $_ = $self->_bb2html($_, $alwd{code}, $alwd{list}, $alwd{html}) if $alwd{code} || $alwd{list} || $alwd{html}; | ||
| 33 | |||||||
| 38 | 24 | 50 | 59 | if($alwd{b}) { | |||
| 39 | 24 | 49 | s/\[b\]//ig; | ||||
| 40 | 24 | 45 | s/\[\/b\]/<\/b>/ig; | ||||
| 41 | 24 | 50 | 48 | } if($alwd{i}) { | |||
| 42 | 24 | 39 | s/\[i\]//ig; | ||||
| 43 | 24 | 35 | s/\[\/i\]/<\/i>/ig; | ||||
| 44 | 24 | 50 | 49 | } if($alwd{u}) { | |||
| 45 | 24 | 39 | s/\[u\]//ig; | ||||
| 46 | 24 | 35 | s/\[\/u\]/<\/span>/ig; | ||||
| 47 | 24 | 50 | 43 | } if($alwd{img}) { | |||
| 48 | 24 | 32 | s/\[img\]([^"\[]+)\[\/img\]/" |
||||
| 1 | 3 | ||||||
| 49 | 24 | 47 | s/\[img=([^"\]]+)\]([^"\[]+)\[\/img\]/" |
||||
| 2 | 7 | ||||||
| 50 | 24 | 50 | 60 | } if($alwd{url}) { | |||
| 51 | 24 | 41 | s/\[url=([^\]"]+)\]/"_fix_jslink($1) . "\">"/ieg; | ||||
| 3 | 9 | ||||||
| 52 | 24 | 41 | s/\[\/url\]/<\/a>/ig; | ||||
| 53 | 24 | 50 | 46 | } if($alwd{email}) { | |||
| 54 | 24 | 38 | s/\[email\]([^"\[]+)\[\/email\]/$1<\/a>/ig; #" | ||||
| 55 | 24 | 50 | 44 | } if($alwd{size}) { | |||
| 56 | 24 | 30 | s/\[size=([0-9]{1,2})\]//ig; | ||||
| 57 | 24 | 34 | s/\[\/size\]/<\/span>/ig; | ||||
| 58 | 24 | 50 | 43 | } if($alwd{color}) { | |||
| 59 | 24 | 31 | s/\[color=([^"\]\s]+)\]//ig; #" | ||||
| 60 | 24 | 36 | s/\[\/color\]/<\/span>/ig; | ||||
| 61 | 24 | 50 | 45 | } if($alwd{quote}) { | |||
| 62 | 24 | 40 | s/\[quote\]/Quote: /ig; | ||||
| 63 | 24 | 39 | s/\[quote=([^<\]]+)\]/$1 wrote: /ig; | ||||
| 64 | 24 | 43 | s/\[\/quote\]/<\/span><\/span>/ig; | ||||
| 65 | } | ||||||
| 66 | 24 | 28 | s/\[\;/[/g; | ||||
| 67 | 24 | 26 | s/\]\;/]/g; | ||||
| 68 | # s/\r?\n$//; | ||||||
| 69 | # s/\s$//; | ||||||
| 70 | 24 | 91 | return $_; | ||||
| 71 | } | ||||||
| 72 | sub _fix_jslink { | ||||||
| 73 | 6 | 6 | 7 | my $self = shift; | |||
| 74 | 6 | 11 | my $lnk = shift; | ||||
| 75 | 6 | 50 | 21 | $lnk =~ s/^[\s\t]*javascript://g if $self->{no_jslink}; | |||
| 76 | 6 | 50 | return $lnk; | ||||
| 77 | } | ||||||
| 78 | |||||||
| 79 | sub reverse { | ||||||
| 80 | 25 | 25 | 1 | 11755 | my $self = shift; | ||
| 81 | 25 | 61 | local $_ = shift; | ||||
| 82 | |||||||
| 83 | 25 | 100 | 60 | (return '') if !$_; | |||
| 84 | 24 | 24 | my %alwd; | ||||
| 85 | 24 | 25 | foreach my $tag (@{$self->{allowed_tags}}) { $alwd{$tag} = 1 } | ||||
| 24 | 51 | ||||||
| 288 | 378 | ||||||
| 86 | |||||||
| 87 | 24 | 0 | 33 | 110 | $_ = $self->_html2bb($_, $alwd{code}, $alwd{list}, $alwd{html}) if $alwd{code} || $alwd{list} || $alwd{html}; | ||
| 33 | |||||||
| 88 | 24 | 50 | 55 | if($alwd{b}) { | |||
| 89 | 24 | 48 | s//[b]/g; | ||||
| 90 | 24 | 37 | s/<\/b>/[\/b]/g; | ||||
| 91 | 24 | 50 | 45 | } if($alwd{i}) { | |||
| 92 | 24 | 37 | s//[i]/g; | ||||
| 93 | 24 | 30 | s/<\/i>/[\/i]/g; | ||||
| 94 | 24 | 50 | 47 | } if($alwd{u}) { | |||
| 95 | 24 | 31 | s//[u]/g; | ||||
| 96 | 24 | 30 | s/<\/span>/[\/u]/g; | ||||
| 97 | 24 | 50 | 51 | } if($alwd{img}) { | |||
| 98 | 24 | 30 | s/ |
||||
| 99 | 24 | 45 | s/ |
||||
| 100 | 24 | 50 | 44 | } if($alwd{email}) { | |||
| 101 | 24 | 35 | s/\1<\/a>/\[email\]$1\[\/email\]/g; #" | ||||
| 102 | 24 | 50 | 48 | } if($alwd{url}) { | |||
| 103 | 24 | 46 | s//\[url=$1\]/g; #" | ||||
| 104 | 24 | 34 | s/<\/a>/\[\/url\]/g; | ||||
| 105 | 24 | 50 | 42 | } if($alwd{size}) { | |||
| 106 | 24 | 30 | s//\[size=$1\]/g; | ||||
| 107 | 24 | 32 | s/<\/span>/\[\/size\]/g; | ||||
| 108 | 24 | 50 | 43 | } if($alwd{color}) { | |||
| 109 | 24 | 26 | s//\[color=$1\]/g; #" | ||||
| 110 | 24 | 28 | s/<\/span>/\[\/color\]/g; | ||||
| 111 | 24 | 50 | 45 | } if($alwd{quote}) { | |||
| 112 | 24 | 28 | s/Quote: /\[quote\]/g; | ||||
| 113 | 24 | 502 | s/([^<\]]+) wrote: /\[quote=$1\]/g; | ||||
| 114 | 24 | 34 | s/<\/span><\/span>/\[\/quote\]/g; | ||||
| 115 | } | ||||||
| 116 | 24 | 41 | s/ \r?\n/\n/g; |
||||
| 117 | 24 | 50 | 51 | if(!$self->{reverse_for_edit}) { | |||
| 118 | 0 | 0 | s/\>\;/>/g; | ||||
| 119 | 0 | 0 | s/\<\;/ | ||||
| 120 | 0 | 0 | s/\&\;/\&/g; | ||||
| 121 | } | ||||||
| 122 | |||||||
| 123 | 24 | 142 | return $_; | ||||
| 124 | } | ||||||
| 125 | |||||||
| 126 | |||||||
| 127 | |||||||
| 128 | ## Parses the BB code, list and html tags | ||||||
| 129 | sub _bb2html { | ||||||
| 130 | 24 | 24 | 27 | my $self = shift; | |||
| 131 | 24 | 27 | my $str = shift; | ||||
| 132 | 24 | 28 | my($acode, $alist, $ahtml) = @_; | ||||
| 133 | 24 | 30 | my $return = ""; | ||||
| 134 | |||||||
| 135 | 24 | 23 | my $incode = 0; my $inhtml = 0; | ||||
| 24 | 20 | ||||||
| 136 | 24 | 20 | my $inlist = 0; my $liststart = 0; | ||||
| 24 | 20 | ||||||
| 137 | 24 | 141 | while($str =~ /\[(\/?)(code|list|html|\*)=?([^\]])*\](.*)$/ims) { | ||||
| 138 | 16 | 44 | $str = $4; | ||||
| 139 | 16 | 100 | 63 | my($be4, $end, $tag, $opt, $done, $app) = ($`, ($1 eq '/' ? 1 : 0), $2, $3, 0, 0); | |||
| 140 | # Parse the stuff before the tag... (if any) | ||||||
| 141 | 16 | 100 | 100 | 115 | if($be4 && $incode) { | ||
| 50 | 66 | ||||||
| 50 | 66 | ||||||
| 66 | |||||||
| 142 | 3 | 50 | 33 | 10 | if(lc($tag) ne 'code' && !$end) { | ||
| 143 | 0 | 0 | $be4 .= _appendtag($end, $tag, $opt); | ||||
| 144 | 0 | 0 | $app++; | ||||
| 145 | } | ||||||
| 146 | 3 | 4 | $be4 =~ s/\[/\[\;/g; | ||||
| 147 | 3 | 4 | $be4 =~ s/\]/\]\;/g; | ||||
| 148 | } elsif($be4 && $inlist && $inlist != $liststart) { | ||||||
| 149 | 0 | 0 | $be4 = ''; | ||||
| 150 | } elsif($be4 && $inhtml) { | ||||||
| 151 | 0 | 0 | 0 | 0 | if(lc($tag) ne 'html' && !$end) { | ||
| 152 | 0 | 0 | $be4 .= _appendtag($end, $tag, $opt); | ||||
| 153 | 0 | 0 | $app++; | ||||
| 154 | } | ||||||
| 155 | 0 | 0 | $be4 =~ s/ \r?\n/\n/g; |
||||
| 156 | 0 | 0 | $be4 =~ s/\>\;/>/g; | ||||
| 157 | 0 | 0 | $be4 =~ s/\<\;/ | ||||
| 158 | 0 | 0 | $be4 =~ s/\&\;/\&/g; | ||||
| 159 | 0 | 0 | $be4 =~ s/\[/\[\;/g; | ||||
| 160 | 0 | 0 | $be4 =~ s/\]/\]\;/g; | ||||
| 161 | } | ||||||
| 162 | 16 | 100 | 34 | $return .= $be4 if $be4; | |||
| 163 | # The [code]-tag | ||||||
| 164 | 16 | 50 | 33 | 68 | if($acode && !$inhtml) { | ||
| 165 | 16 | 100 | 100 | 154 | if(!$incode && lc($tag) eq 'code' && !$end) { | ||
| 100 | 66 | ||||||
| 66 | |||||||
| 100 | |||||||
| 166 | 3 | 7 | $return .= "Code: "; | ||||
| 167 | 3 | 3 | $incode = 1; | ||||
| 168 | 3 | 4 | $done++; | ||||
| 169 | } elsif($incode && lc($tag) eq 'code' && $end) { | ||||||
| 170 | 3 | 4 | $return .= " "; | ||||
| 171 | 3 | 3 | $incode = 0; | ||||
| 172 | 3 | 3 | $done++; | ||||
| 173 | } | ||||||
| 174 | } | ||||||
| 175 | # The [list] and [*]-tags | ||||||
| 176 | 16 | 100 | 66 | 89 | if($alist && !$incode && !$inhtml) { | ||
| 66 | |||||||
| 177 | 12 | 100 | 100 | 75 | if(lc($tag) eq 'list' && !$end) { | ||
| 100 | 66 | ||||||
| 100 | |||||||
| 178 | 3 | 50 | 33 | 24 | $return .= '' if !$inlist && $self->{in_paragraph}; | ||
| 179 | 3 | 50 | 8 | $return .= '
|
|||
| 180 | 3 | 50 | 33 | 10 | $return .= '
|
||
| 181 | 3 | 50 | 33 | 9 | $return .= '
|
||
| 182 | 3 | 5 | $return .= "\n"; | ||||
| 183 | 3 | 4 | $inlist++; | ||||
| 184 | 3 | 3 | $done++; | ||||
| 185 | } elsif(lc($tag) eq 'list' && $end) { | ||||||
| 186 | 3 | 4 | $return .= ''; | ||||
| 187 | 3 | 50 | 33 | 16 | $return .= ' ' if $inlist == 1 && $self->{in_paragraph}; |
||
| 188 | 3 | 3 | $liststart = --$inlist; | ||||
| 189 | 3 | 5 | $done++; | ||||
| 190 | } elsif(lc($tag) eq '*') { | ||||||
| 191 | 3 | 50 | 8 | $return .= '' if $liststart == $inlist; | |||
| 192 | 3 | 4 | $return .= ' |
||||
| 193 | 3 | 4 | $liststart = $inlist; | ||||
| 194 | 3 | 3 | $done++; | ||||
| 195 | } | ||||||
| 196 | } | ||||||
| 197 | # The [html]-tag | ||||||
| 198 | 16 | 100 | 66 | 62 | if($ahtml && !$incode) { | ||
| 199 | 12 | 50 | 33 | 91 | if(!$inhtml && lc($tag) eq 'html' && !$end) { | ||
| 50 | 33 | ||||||
| 33 | |||||||
| 33 | |||||||
| 200 | 0 | 0 | $return .= ""; | ||||
| 201 | 0 | 0 | $inhtml = 1; | ||||
| 202 | 0 | 0 | $done++; | ||||
| 203 | } elsif($inhtml && lc($tag) eq 'html' && $end) { | ||||||
| 204 | 0 | 0 | $return .= ""; | ||||
| 205 | 0 | 0 | $inhtml = 0; | ||||
| 206 | 0 | 0 | $done++; | ||||
| 207 | } | ||||||
| 208 | } | ||||||
| 209 | # When nothing is done with the tag, just add it... (fixes bug added in 0.05) | ||||||
| 210 | 16 | 50 | 66 | 87 | $return .= _appendtag($end, $tag, $opt) if !$done && !$app; | ||
| 211 | } | ||||||
| 212 | 24 | 59 | return $return . $str; | ||||
| 213 | } | ||||||
| 214 | sub _appendtag { | ||||||
| 215 | 1 | 1 | 2 | my $tag = '['; | |||
| 216 | 1 | 50 | 5 | $tag .= '/' if $_[0]; | |||
| 217 | 1 | 2 | $tag .= $_[1]; | ||||
| 218 | 1 | 50 | 4 | $tag .= "=$_[2]" if $_[2]; | |||
| 219 | 1 | 7 | return "$tag]"; | ||||
| 220 | } | ||||||
| 221 | |||||||
| 222 | |||||||
| 223 | sub _html2bb { | ||||||
| 224 | 24 | 24 | 27 | my $self = shift; | |||
| 225 | 24 | 28 | my $str = shift; | ||||
| 226 | 24 | 31 | my($acode, $alist, $ahtml) = @_; | ||||
| 227 | 24 | 29 | my $return = ""; | ||||
| 228 | |||||||
| 229 | 24 | 24 | my $incode = 0; my $inhtml = 0; | ||||
| 24 | 18 | ||||||
| 230 | 24 | 22 | my $inlist = 0; | ||||
| 231 | 24 | 83 | $str =~ s/(?:<\/p>| |<\/li>)//g; |
||||
| 232 | # And this definately is one of the most ugly RegEx-es I've ever written | ||||||
| 233 | 24 | 107 | while($str =~ /(Code:\ |<\/span>\ <\/span> | ||||
| 234 | |
|
||||||
| 235 | ||)(.*)$/xms) | ||||||
| 236 | { | ||||||
| 237 | 15 | 29 | $str = $2; | ||||
| 238 | 15 | 33 | my($be4, $code, $done) = ($`, $1, 0); | ||||
| 239 | # Parse the stuff before the tag... (if any) | ||||||
| 240 | 15 | 50 | 66 | 54 | if($be4 && $inhtml) { | ||
| 241 | 0 | 0 | 0 | $be4 .= $code if $code ne ''; | |||
| 242 | 0 | 0 | $be4 =~ s/\&/\&\;/g; | ||||
| 243 | 0 | 0 | $be4 =~ s/\<\;/g; | ||||
| 244 | 0 | 0 | $be4 =~ s/>/\>\;/g; | ||||
| 245 | } | ||||||
| 246 | 15 | 100 | 29 | $return .= $be4 if $be4; | |||
| 247 | # The code-tag | ||||||
| 248 | 15 | 50 | 33 | 62 | if($acode && !$inhtml) { | ||
| 249 | 15 | 100 | 100 | 86 | if(!$incode && $code eq 'Code: ') { | ||
| 100 | 66 | ||||||
| 250 | 3 | 5 | $return .= '[code]'; | ||||
| 251 | 3 | 3 | $incode = 1; | ||||
| 252 | 3 | 4 | $done++; | ||||
| 253 | } elsif($incode && $code eq ' ') { | ||||||
| 254 | 3 | 4 | $return .= '[/code]'; | ||||
| 255 | 3 | 3 | $incode = 0; | ||||
| 256 | 3 | 4 | $done++; | ||||
| 257 | } | ||||||
| 258 | } | ||||||
| 259 | # The list-tags | ||||||
| 260 | 15 | 100 | 66 | 83 | if($alist && !$incode && !$inhtml) { | ||
| 66 | |||||||
| 261 | 12 | 100 | 66 | 87 | if($code eq '
|
||
| 100 | 66 | ||||||
| 100 | |||||||
| 262 | 3 | 50 | 10 | $return .= '[list]' if $code eq '
|
|||
| 263 | 3 | 50 | 10 | $return .= '[list=1]' if $code eq '
|
|||
| 264 | 3 | 50 | 9 | $return .= '[list=a]' if $code eq '
|
|||
| 265 | 3 | 4 | $inlist++; | ||||
| 266 | 3 | 5 | $done++; | ||||
| 267 | } elsif($code eq '') { | ||||||
| 268 | 3 | 4 | $return .= '[/list]'; | ||||
| 269 | 3 | 5 | $inlist--; | ||||
| 270 | 3 | 5 | $done++; | ||||
| 271 | } elsif($code eq ' |
||||||
| 272 | 3 | 4 | $return .= '[*]'; | ||||
| 273 | 3 | 4 | $done++; | ||||
| 274 | } | ||||||
| 275 | } | ||||||
| 276 | # The html-tag | ||||||
| 277 | 15 | 100 | 66 | 62 | if($ahtml && !$incode) { | ||
| 278 | 12 | 50 | 33 | 68 | if(!$inhtml && $code eq '') { | ||
| 50 | 33 | ||||||
| 279 | 0 | 0 | $return .= '[html]'; | ||||
| 280 | 0 | 0 | $inhtml = 1; | ||||
| 281 | 0 | 0 | $done++; | ||||
| 282 | } elsif($inhtml && $code eq '') { | ||||||
| 283 | 0 | 0 | $return .= '[/html]'; | ||||
| 284 | 0 | 0 | $inhtml = 0; | ||||
| 285 | 0 | 0 | $done++; | ||||
| 286 | } | ||||||
| 287 | } | ||||||
| 288 | 15 | 50 | 33 | 82 | $return .= $code if !$done && $code ne ''; | ||
| 289 | } | ||||||
| 290 | 24 | 60 | return $return . $str; | ||||
| 291 | } | ||||||
| 292 | |||||||
| 293 | 1; | ||||||
| 294 | |||||||
| 295 | __END__ |