File Coverage

lib/Petal/Parser.pm
Criterion Covered Total %
statement 139 140 99.2
branch 42 48 87.5
condition 1 3 33.3
subroutine 15 16 93.7
pod 0 8 0.0
total 197 215 91.6


line stmt bran cond sub pod time code
1             # ------------------------------------------------------------------
2             # Petal::Parser - Fires Petal::Canonicalizer events
3             # ------------------------------------------------------------------
4             # A Wrapper class for MKDoc::XML:TreeBuilder which is meant to be
5             # used for Petal::Canonicalizer.
6             # ------------------------------------------------------------------
7             package Petal::Parser;
8 77     77   31929 use MKDoc::XML::TreeBuilder;
  77         291282  
  77         2195  
9 77     77   31428 use MKDoc::XML::Decode;
  77         317614  
  77         2311  
10 77     77   484 use strict;
  77         129  
  77         1368  
11 77     77   340 use warnings;
  77         132  
  77         1570  
12 77     77   344 use Carp;
  77         120  
  77         3959  
13              
14 77     77   29686 use Petal::Canonicalizer::XML;
  77         219  
  77         2398  
15 77     77   26950 use Petal::Canonicalizer::XHTML;
  77         202  
  77         2610  
16              
17 77         111311 use vars qw /@NodeStack @MarkedData $Canonicalizer
18 77     77   2597 @NameSpaces @XI_NameSpaces @MT_NameSpaces @MT_Name_Cur $Decode/;
  77         227  
19              
20              
21             # this avoid silly warnings
22             sub sillyness
23             {
24 0     0 0 0 $Petal::NS,
25             $Petal::NS_URI,
26             $Petal::XI_NS_URI;
27             }
28              
29              
30             sub new
31             {
32 206     206 0 369 my $class = shift;
33 206   33     766 $class = ref $class || $class;
34 206         544 return bless { @_ }, $class;
35             }
36              
37              
38             sub process
39             {
40 206     206 0 322 my $self = shift;
41 206         374 local $Canonicalizer = shift;
42 206         284 my $data_ref = shift;
43            
44 206         331 local @MarkedData = ();
45 206         322 local @NodeStack = ();
46 206         316 local @NameSpaces = ();
47 206         294 local @MT_NameSpaces = ();
48 206         479 local @MT_Name_Cur = ('main');
49 206         557 local $Decode = new MKDoc::XML::Decode (qw /xml numeric/);
50            
51 206 50       2892 $data_ref = (ref $data_ref) ? $data_ref : \$data_ref;
52            
53 206         1051 my @top_nodes = MKDoc::XML::TreeBuilder->process_data ($$data_ref);
54 202         1342421 for (@top_nodes) { $self->generate_events ($_) }
  234         795  
55            
56 202         425 @MarkedData = ();
57 202         2893 @NodeStack = ();
58             }
59              
60              
61             # generate_events();
62             # ------------------
63             # Once the HTML::TreeBuilder object is built and elementified, it is
64             # passed to that subroutine which will traverse it and will trigger
65             # proper subroutines which will generate the XML events which are used
66             # by the Petal::Canonicalizer module
67             sub generate_events
68             {
69 3687     3687 0 4566 my $self = shift;
70 3687         4688 my $tree = shift;
71            
72 3687 100       6586 if (ref $tree)
73             {
74 1484         2628 my $tag = $tree->{_tag};
75 1484 100       1681 my $attr = { map { /^_/ ? () : ( $_ => $Decode->process ($tree->{$_}) ) } keys %{$tree} };
  7897         41327  
  1484         5067  
76            
77 1484 100       9884 if ($tag eq '~comment')
78             {
79 13         34 generate_events_comment ($tree->{text});
80             }
81             else
82             {
83             # decode attributes
84 1471         1755 for (keys %{$tree})
  1471         3909  
85             {
86 7871 100       39006 $tree->{$_} = $Decode->process ( $tree->{$_} )
87             unless (/^_/);
88             }
89            
90 1471         7111 push @NodeStack, $tree;
91 1471         3524 generate_events_start ($tag, $attr);
92            
93 1471         2106 foreach my $content (@{$tree->{_content}})
  1471         3654  
94             {
95 3453         6947 $self->generate_events ($content);
96             }
97            
98 1471         3331 generate_events_end ($tag);
99 1471         4141 pop (@NodeStack);
100             }
101             }
102             else
103             {
104 2203         5195 $tree = $Decode->process ( $tree );
105 2203         27714 generate_events_text ($tree);
106             }
107             }
108              
109              
110             sub generate_events_start
111             {
112 1471     1471 0 2358 local $_ = shift;
113 1471         3002 $_ = "<$_>";
114 1471         1952 local %_ = %{shift()};
  1471         5542  
115 1471         2489 delete $_{'/'};
116            
117             # process the Petal namespace
118 1471 100       3120 my $ns = (scalar @NameSpaces) ? $NameSpaces[$#NameSpaces] : $Petal::NS;
119 1471         3674 foreach my $key (keys %_)
120             {
121 2422         3642 my $value = $_{$key};
122 2422 100       5138 if ($value eq $Petal::NS_URI)
123             {
124 55 50       229 next unless ($key =~ /^xmlns\:/);
125 55         128 delete $_{$key};
126 55         86 $ns = $key;
127 55         221 $ns =~ s/^xmlns\://;
128             }
129             }
130            
131 1471         2420 push @NameSpaces, $ns;
132 1471         2230 local ($Petal::NS) = $ns;
133            
134             # process the XInclude namespace
135 1471 100       2731 my $xi_ns = (scalar @XI_NameSpaces) ? $XI_NameSpaces[$#XI_NameSpaces] : $Petal::XI_NS;
136 1471         2674 foreach my $key (keys %_)
137             {
138 2367         3332 my $value = $_{$key};
139 2367 100       4195 if ($value eq $Petal::XI_NS_URI)
140             {
141 39 50       111 next unless ($key =~ /^xmlns\:/);
142 39         67 delete $_{$key};
143 39         53 $xi_ns = $key;
144 39         137 $xi_ns =~ s/^xmlns\://;
145             }
146             }
147            
148 1471         2247 push @XI_NameSpaces, $xi_ns;
149 1471         1930 local ($Petal::XI_NS) = $xi_ns;
150            
151             # process the Metal namespace
152 1471 100       2833 my $mt_ns = (scalar @MT_NameSpaces) ? $MT_NameSpaces[$#MT_NameSpaces] : $Petal::MT_NS;
153 1471         2642 foreach my $key (keys %_)
154             {
155 2328         3200 my $value = $_{$key};
156 2328 100       4247 if ($value eq $Petal::MT_NS_URI)
157             {
158 10 50       53 next unless ($key =~ /^xmlns\:/);
159 10         23 delete $_{$key};
160 10         15 $mt_ns = $key;
161 10         50 $mt_ns =~ s/^xmlns\://;
162             }
163             }
164            
165 1471         2161 push @MT_NameSpaces, $mt_ns;
166 1471         2030 local ($Petal::MT_NS) = $mt_ns;
167              
168             # process the Metal current name
169 1471         1733 my $pushed = 0;
170              
171 1471 100       3304 $_{"$mt_ns:define-macro"} and do {
172 44         52 $pushed = 1;
173 44         79 delete $_{"$mt_ns:define-slot"};
174 44         98 push @MT_Name_Cur, delete $_{"$mt_ns:define-macro"};
175             };
176            
177 1471 100       2912 $_{"$mt_ns:fill-slot"} and do {
178 8         11 $pushed = 1;
179 8         29 push @MT_Name_Cur, "__metal_slot__" . delete $_{"$mt_ns:fill-slot"};
180             };
181              
182 1471 100       3120 push @MT_Name_Cur, $MT_Name_Cur[$#MT_Name_Cur] unless ($pushed);
183              
184 1471         11975 my $dont_skip = grep /^\Q$Petal::MT_NAME_CUR\E$/, @MT_Name_Cur;
185 1471 100       5962 $Canonicalizer->StartTag() if ($dont_skip);
186             }
187              
188              
189             sub generate_events_end
190             {
191 1471     1471 0 2332 local $_ = shift;
192 1471         3053 local $_ = "";
193 1471         2569 local ($Petal::NS) = pop (@NameSpaces);
194 1471         2025 local ($Petal::XI_NS) = pop (@XI_NameSpaces);
195 1471         1914 local ($Petal::MT_NS) = pop (@MT_NameSpaces);
196            
197 1471         1863 my $skip = 1;
198 1471 100       2081 for (@MT_Name_Cur) { $_ eq $Petal::MT_NAME_CUR and $skip = 0 }
  6607         10668  
199              
200 1471         10820 my $dont_skip = grep /^\Q$Petal::MT_NAME_CUR\E$/, @MT_Name_Cur;
201 1471 100       5284 $Canonicalizer->EndTag() if ($dont_skip);
202 1471         2749 pop (@MT_Name_Cur);
203             }
204              
205              
206             sub generate_events_text
207             {
208              
209 2203     2203 0 2642 my $skip = 1;
210 2203 100       3463 for (@MT_Name_Cur) { $_ eq $Petal::MT_NAME_CUR and $skip = 0 }
  9190         14910  
211            
212 2203         2866 my $data = shift;
213 2203         3467 $data =~ s/\&/&/g;
214 2203         2829 $data =~ s/\
215 2203         2951 local $_ = $data;
216 2203         3850 local ($Petal::NS) = $NameSpaces[$#NameSpaces];
217 2203         3329 local ($Petal::XI_NS) = $XI_NameSpaces[$#XI_NameSpaces];
218 2203         3285 local ($Petal::MT_NS) = $MT_NameSpaces[$#MT_NameSpaces];
219              
220 2203         16362 my $dont_skip = grep /^\Q$Petal::MT_NAME_CUR\E$/, @MT_Name_Cur;
221 2203 100       7230 $Canonicalizer->Text() if ($dont_skip);
222             }
223              
224              
225             sub generate_events_comment
226             {
227 13     13 0 23 my $skip = 1;
228 13 50       29 for (@MT_Name_Cur) { $_ eq $Petal::MT_NAME_CUR and $skip = 0 }
  33         89  
229            
230 13         20 my $data = shift;
231 13         52 local $_ = '';
232            
233 13         141 my $dont_skip = grep /^\Q$Petal::MT_NAME_CUR\E$/, @MT_Name_Cur;
234 13 50       61 $Canonicalizer->Text() if ($dont_skip);
235             }
236              
237              
238             1;
239              
240              
241             __END__