File Coverage

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/
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\]/"_fix_jslink($1) . "\" alt=\"\" \/>"/eig; #"
  1         3  
49 24         47 s/\[img=([^"\]]+)\]([^"\[]+)\[\/img\]/"_fix_jslink($1) . "\" alt=\"$2\" title=\"$2\" \/>"/eig; #"
  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/\"\"/\[img\]$1\[\/img\]/g; #"
99 24         45 s/\"([^"\[]+)\"/\[img=$1\]$2\[\/img\]/g; #"
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 .= '
    ' if !$opt;
180 3 50 33     10 $return .= '
    ' if $opt && $opt eq '1';
181 3 50 33     9 $return .= '
    ' if $opt && lc($opt) eq 'a';
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             |
      |||
    • |<\/ul>
    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/
    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 '
      ' || $code eq '
        ' || $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__