File Coverage

blib/lib/HTML/WikiConverter/GoogleCode.pm
Criterion Covered Total %
statement 15 76 19.7
branch 0 32 0.0
condition 0 16 0.0
subroutine 5 15 33.3
pod 5 5 100.0
total 25 144 17.3


line stmt bran cond sub pod time code
1             package HTML::WikiConverter::GoogleCode;
2            
3 3     3   87883 use warnings;
  3         8  
  3         97  
4 3     3   14 use strict;
  3         5  
  3         104  
5            
6 3     3   13 use base 'HTML::WikiConverter';
  3         10  
  3         1500  
7 3     3   2852 use Params::Validate ':types';
  3         33348  
  3         741  
8 3     3   8694 use URI;
  3         28103  
  3         3967  
9            
10             =head1 NAME
11            
12             HTML::WikiConverter::GoogleCode - Convert HTML to Google Code wiki markup.
13            
14             =head1 SYNOPSIS
15            
16             use HTML::WikiConverter;
17             my $wc = new HTML::WikiConverter( dialect => 'GoogleCode' );
18             print $wc->html2wiki( $html );
19            
20             =head1 DESCRIPTION
21            
22             This module contains rules for converting HTML into Google Code wiki
23             markup. See L for additional usage details.
24            
25             =head1 VERSION
26            
27             Version 0.12
28            
29             =cut
30            
31             our $VERSION = '0.12';
32            
33            
34             =head1 FUNCTIONS
35            
36             =head2 rules
37            
38             Returns the HTML to wiki conversion rules
39            
40             =cut
41            
42             sub rules {
43 0     0 1   my %rules = (
44             p => { block => 1, trim => 'both', line_format => 'multi' },
45             pre => { block => 1, start => "{{{\n", end => "\n}}}" },
46            
47             i => { start => "_", end => "_", line_format => 'single' },
48             em => { alias => 'i' },
49             b => { start => "*", end => "*", line_format => 'single' },
50             strong => { alias => 'b' },
51             #u => { start => '__', end => '__', line_format => 'single' },
52            
53             sup => { start => '^', end => '^', line_format => 'single' },
54             sub => { start => ',,', end => ',,', line_format => 'single' },
55             code => { start => '`', end => '`', line_format => 'single' },
56             tt => { alias => 'code' },
57             #small => { start => '~-', end => '-~', line_format => 'single' },
58             #big => { start => '~+', end => '+~', line_format => 'single' },
59            
60             a => { replace => \&_link },
61             img => { replace => \&_image },
62            
63             ul => { line_format => 'multi', block => 1, line_prefix => ' ' },
64             ol => { alias => 'ul' },
65            
66             li => { start => \&_li_start, trim => 'leading' },
67            
68             #dl => { line_format => 'multi' },
69             #dt => { trim => 'both', end => ':: ' },
70             #dd => { trim => 'both' },
71            
72             hr => { replace => "\n----\n"},
73             br => { replace => "\n" },
74            
75             table => { block => 1, line_format => 'multi' },
76             tr => { end => "||\n", line_format => 'single' },
77             td => { start => '|| ', end => ' ', trim => 'both' },
78             th => { alias => 'td' },
79             );
80            
81             # Headings (h1-h6)
82 0           my @headings = ( 1..6 );
83 0           foreach my $level ( @headings ) {
84 0           my $tag = "h$level";
85 0           my $affix = ( '=' ) x ($level);
86 0 0         $affix = '======' if $level == 6;
87 0           $rules{$tag} = { start => $affix.' ', end => ' '.$affix, block => 1, trim => 'both', line_format => 'single' };
88             }
89            
90 0           return \%rules;
91             }
92            
93             =head2 attributes
94            
95             Returns the conversion L particular to the GoogleCode dialect
96            
97             =cut
98            
99             sub attributes { {
100 0     0 1   escape_autolink => {default => [], type => ARRAYREF},
101             summary => {default => 0, type => SCALAR},
102             labels => {default => [], type => ARRAYREF}
103             }}
104            
105             sub _li_start {
106 0     0     my( $self, $node, $rules ) = @_;
107 0           my $bullet = '';
108 0 0         $bullet = '*' if $node->parent->tag eq 'ul';
109 0 0         $bullet = '#' if $node->parent->tag eq 'ol';
110 0           return "\n$bullet ";
111             }
112            
113             sub _link {
114 0     0     my( $self, $node, $rules ) = @_;
115            
116             # (bug #17813)
117 0           my $name = $node->attr('name');
118            
119 0   0       my $url = $node->attr('href') || '';
120 0   0       my $text = $self->get_elem_contents($node) || '';
121            
122             # (bug #17813)
123 0 0         if( $self->_abs2rel($url) =~ /^#/ ) {
124 0           $url = $self->_abs2rel($url);
125             }
126            
127 0 0         return $url if $url eq $text;
128 0           return "[$url $text]";
129             }
130            
131             sub _abs2rel {
132 0     0     my( $self, $uri ) = @_;
133 0 0         return $uri unless $self->base_uri;
134 0           return URI->new($uri)->rel($self->base_uri)->as_string;
135             }
136            
137             sub _image {
138 0     0     my( $self, $node, $rules ) = @_;
139 0 0         return $node->attr('src') ? ('[' . $node->attr('src') . ']') : '';
140             }
141            
142             =head2 preprocess_node
143            
144             HTML element specific pre-processing
145            
146             =cut
147            
148             sub preprocess_node {
149 0     0 1   my( $self, $node ) = @_;
150            
151 0 0 0       $self->strip_aname($node) if $node->tag and $node->tag eq 'a';
152 0 0 0       $self->caption2para($node) if $node->tag and $node->tag eq 'caption';
153            
154             # (bug #17813)
155 0 0 0       if($node->tag and $node->tag eq 'a' and $node->attr('name') ) {
      0        
156 0           my $name = $node->attr('name');
157 0           $node->preinsert( new HTML::Element('a', name => $name) );
158 0           $node->attr( name => undef );
159             }
160            
161             }
162            
163             =head2 preprocess_tree
164            
165             HTML document specific pre-processing
166            
167             =cut
168            
169             sub preprocess_tree {
170 0     0 1   my ($self, $root) = @_;
171 0           $self->_escape_autolink($root);
172             }
173            
174             # escape Google wiki autolinking of specific CamelCase words
175             # words in attribute escape_autolink
176             sub _escape_autolink {
177 0     0     my ($self, $parent) = @_;
178 0           foreach my $child ($parent->content_list) {
179 0 0         if($child->tag eq '~text') {
180 0           my %toChange;
181 0           my $theText = $child->attr('text');
182 0           while($theText =~ /\b(\w+)\b/g) {
183 0 0         if ($self->is_camel_case($1)) {
184 0 0         if(grep(/^$1$/, @{$self->escape_autolink})) {
  0            
185 0           $toChange{$1} = undef;
186             }
187             }
188             }
189 0           foreach my $val (keys %toChange) {
190 0           $theText =~ s/$val/!$val/g;
191             }
192 0           $child->attr('text', $theText);
193             } else {
194 0 0         unless($child->tag eq 'pre') {
195 0           $self->_escape_autolink($child);
196             }
197             }
198             }
199             }
200            
201             my @protocols = qw( http https mailto );
202             my $urls = '(' . join('|', @protocols) . ')';
203             my $ltrs = '\w';
204             my $gunk = '\/\#\~\:\.\?\+\=\&\%\@\!\-';
205             my $punc = '\.\:\?\-\{\(\)\}';
206             my $any = "${ltrs}${gunk}${punc}";
207             my $url_re = "\\b($urls:\[$any\]+?)(?=\[$punc\]*\[^$any\])";
208            
209             =head2 postprocess_output
210            
211             Wiki document post-processing
212            
213             =cut
214            
215             sub postprocess_output {
216 0     0 1   my( $self, $outref ) = @_;
217 0           $$outref =~ s/($url_re)\[\[BR\]\]/$1 [[BR]]/go;
218            
219             # add 'summary' and 'labels' wiki markup elements
220 0           my $additional_markup = '';
221 0 0         if($self->summary) {
222 0           $additional_markup = '#summary ' . $self->summary . "\n";
223             }
224 0 0         if(@{$self->labels}) {
  0            
225 0           $additional_markup .= '#labels ' . join(',', @{$self->labels}) . "\n";
  0            
226             }
227 0           $$outref = $additional_markup . $$outref;
228             }
229            
230            
231             =head1 ATTRIBUTES
232            
233             In addition to the regular set of attributes recognized by the
234             HTML::WikiConverter constructor, this dialect also accepts the
235             following attributes that can be passed into the C
236             constructor. See L for usage details.
237            
238             =head2 escape_autolink
239            
240             A reference to an array of CamelCase words for which Google Code wiki
241             autolink-ing should be escaped by preceeding the word with a !.
242            
243             =head2 summary
244            
245             Text to be produced in the 'summary' wiki markup element. The summary element
246             appears in the index page of the project's wiki.
247            
248             =head2 labels
249            
250             A reference to an array of text values to be produced in the 'labels' wiki markup
251             element. Allowed values for a project can be found on the project's Google
252             Code web-site on the C tab.
253            
254             =head1 AUTHOR
255            
256             Marty Kube, C<< >>
257            
258             =head1 BUGS
259            
260             Please report any bugs or feature requests to
261             C, or through the web interface at
262             L.
263             I will be notified, and then you'll automatically be notified of progress on
264             your bug as I make changes.
265            
266             =head1 SUPPORT
267            
268             You can find documentation for this module with the perldoc command.
269            
270             perldoc HTML::WikiConverter::GoogleCode
271            
272             You can also look for information at:
273            
274             =over 4
275            
276             =item * AnnoCPAN: Annotated CPAN documentation
277            
278             L
279            
280             =item * CPAN Ratings
281            
282             L
283            
284             =item * RT: CPAN's request tracker
285            
286             L
287            
288             =item * Search CPAN
289            
290             L
291            
292             =back
293            
294             =head1 ACKNOWLEDGEMENTS
295            
296             This module is based on the L module by
297             David J. Iberri, C<< >>
298            
299             =head1 COPYRIGHT & LICENSE
300            
301             Copyright 2008 Marty Kube, all rights reserved.
302            
303             This program is free software; you can redistribute it and/or modify it
304             under the same terms as Perl itself.
305            
306             =cut
307            
308             1; # End of HTML::WikiConverter::GoogleCode