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   35819 use MKDoc::XML::TreeBuilder;
  77         311756  
  77         2248  
9 77     77   33951 use MKDoc::XML::Decode;
  77         340804  
  77         2393  
10 77     77   523 use strict;
  77         144  
  77         1412  
11 77     77   363 use warnings;
  77         139  
  77         1639  
12 77     77   352 use Carp;
  77         125  
  77         4080  
13              
14 77     77   32305 use Petal::Canonicalizer::XML;
  77         196  
  77         2586  
15 77     77   29818 use Petal::Canonicalizer::XHTML;
  77         212  
  77         2781  
16              
17 77         115387 use vars qw /@NodeStack @MarkedData $Canonicalizer
18 77     77   512 @NameSpaces @XI_NameSpaces @MT_NameSpaces @MT_Name_Cur $Decode/;
  77         126  
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 473 my $class = shift;
33 206   33     804 $class = ref $class || $class;
34 206         625 return bless { @_ }, $class;
35             }
36              
37              
38             sub process
39             {
40 206     206 0 327 my $self = shift;
41 206         396 local $Canonicalizer = shift;
42 206         276 my $data_ref = shift;
43              
44 206         383 local @MarkedData = ();
45 206         345 local @NodeStack = ();
46 206         328 local @NameSpaces = ();
47 206         337 local @MT_NameSpaces = ();
48 206         499 local @MT_Name_Cur = ('main');
49 206         648 local $Decode = new MKDoc::XML::Decode (qw /xml numeric/);
50              
51 206 50       2947 $data_ref = (ref $data_ref) ? $data_ref : \$data_ref;
52              
53 206         1202 my @top_nodes = MKDoc::XML::TreeBuilder->process_data ($$data_ref);
54 202         1331917 for (@top_nodes) { $self->generate_events ($_) }
  234         1230  
55              
56 202         457 @MarkedData = ();
57 202         2861 @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 4596 my $self = shift;
70 3687         5571 my $tree = shift;
71              
72 3687 100       6144 if (ref $tree)
73             {
74 1484         3067 my $tag = $tree->{_tag};
75 1484 100       1735 my $attr = { map { /^_/ ? () : ( $_ => $Decode->process ($tree->{$_}) ) } keys %{$tree} };
  7897         42365  
  1484         5516  
76              
77 1484 100       9500 if ($tag eq '~comment')
78             {
79 13         44 generate_events_comment ($tree->{text});
80             }
81             else
82             {
83             # decode attributes
84 1471         1771 for (keys %{$tree})
  1471         3875  
85             {
86 7871 100       39656 $tree->{$_} = $Decode->process ( $tree->{$_} )
87             unless (/^_/);
88             }
89              
90 1471         7298 push @NodeStack, $tree;
91 1471         3288 generate_events_start ($tag, $attr);
92              
93 1471         2083 foreach my $content (@{$tree->{_content}})
  1471         4001  
94             {
95 3453         7106 $self->generate_events ($content);
96             }
97              
98 1471         3261 generate_events_end ($tag);
99 1471         4453 pop (@NodeStack);
100             }
101             }
102             else
103             {
104 2203         5700 $tree = $Decode->process ( $tree );
105 2203         28020 generate_events_text ($tree);
106             }
107             }
108              
109              
110             sub generate_events_start
111             {
112 1471     1471 0 2434 local $_ = shift;
113 1471         3073 $_ = "<$_>";
114 1471         1928 local %_ = %{shift()};
  1471         5777  
115 1471         2605 delete $_{'/'};
116              
117             # process the Petal namespace
118 1471 100       3260 my $ns = (scalar @NameSpaces) ? $NameSpaces[$#NameSpaces] : $Petal::NS;
119 1471         3643 foreach my $key (keys %_)
120             {
121 2422         3618 my $value = $_{$key};
122 2422 100       4747 if ($value eq $Petal::NS_URI)
123             {
124 55 50       218 next unless ($key =~ /^xmlns\:/);
125 55         118 delete $_{$key};
126 55         95 $ns = $key;
127 55         239 $ns =~ s/^xmlns\://;
128             }
129             }
130              
131 1471         2337 push @NameSpaces, $ns;
132 1471         2260 local ($Petal::NS) = $ns;
133              
134             # process the XInclude namespace
135 1471 100       2960 my $xi_ns = (scalar @XI_NameSpaces) ? $XI_NameSpaces[$#XI_NameSpaces] : $Petal::XI_NS;
136 1471         2812 foreach my $key (keys %_)
137             {
138 2367         3428 my $value = $_{$key};
139 2367 100       4284 if ($value eq $Petal::XI_NS_URI)
140             {
141 39 50       118 next unless ($key =~ /^xmlns\:/);
142 39         68 delete $_{$key};
143 39         50 $xi_ns = $key;
144 39         143 $xi_ns =~ s/^xmlns\://;
145             }
146             }
147              
148 1471         2381 push @XI_NameSpaces, $xi_ns;
149 1471         2199 local ($Petal::XI_NS) = $xi_ns;
150              
151             # process the Metal namespace
152 1471 100       2817 my $mt_ns = (scalar @MT_NameSpaces) ? $MT_NameSpaces[$#MT_NameSpaces] : $Petal::MT_NS;
153 1471         2668 foreach my $key (keys %_)
154             {
155 2328         3178 my $value = $_{$key};
156 2328 100       4171 if ($value eq $Petal::MT_NS_URI)
157             {
158 10 50       30 next unless ($key =~ /^xmlns\:/);
159 10         18 delete $_{$key};
160 10         15 $mt_ns = $key;
161 10         42 $mt_ns =~ s/^xmlns\://;
162             }
163             }
164              
165 1471         2188 push @MT_NameSpaces, $mt_ns;
166 1471         1927 local ($Petal::MT_NS) = $mt_ns;
167              
168             # process the Metal current name
169 1471         1767 my $pushed = 0;
170              
171 1471 100       3369 $_{"$mt_ns:define-macro"} and do {
172 44         39 $pushed = 1;
173 44         75 delete $_{"$mt_ns:define-slot"};
174 44         93 push @MT_Name_Cur, delete $_{"$mt_ns:define-macro"};
175             };
176              
177 1471 100       2857 $_{"$mt_ns:fill-slot"} and do {
178 8         22 $pushed = 1;
179 8         38 push @MT_Name_Cur, "__metal_slot__" . delete $_{"$mt_ns:fill-slot"};
180             };
181              
182 1471 100       3189 push @MT_Name_Cur, $MT_Name_Cur[$#MT_Name_Cur] unless ($pushed);
183              
184 1471         11784 my $dont_skip = grep /^\Q$Petal::MT_NAME_CUR\E$/, @MT_Name_Cur;
185 1471 100       5890 $Canonicalizer->StartTag() if ($dont_skip);
186             }
187              
188              
189             sub generate_events_end
190             {
191 1471     1471 0 2340 local $_ = shift;
192 1471         3180 local $_ = "";
193 1471         2656 local ($Petal::NS) = pop (@NameSpaces);
194 1471         2001 local ($Petal::XI_NS) = pop (@XI_NameSpaces);
195 1471         2181 local ($Petal::MT_NS) = pop (@MT_NameSpaces);
196              
197 1471         1874 my $skip = 1;
198 1471 100       2097 for (@MT_Name_Cur) { $_ eq $Petal::MT_NAME_CUR and $skip = 0 }
  6607         10514  
199              
200 1471         11010 my $dont_skip = grep /^\Q$Petal::MT_NAME_CUR\E$/, @MT_Name_Cur;
201 1471 100       5307 $Canonicalizer->EndTag() if ($dont_skip);
202 1471         2895 pop (@MT_Name_Cur);
203             }
204              
205              
206             sub generate_events_text
207             {
208              
209 2203     2203 0 2831 my $skip = 1;
210 2203 100       3308 for (@MT_Name_Cur) { $_ eq $Petal::MT_NAME_CUR and $skip = 0 }
  9190         14521  
211              
212 2203         2825 my $data = shift;
213 2203         3545 $data =~ s/\&/&/g;
214 2203         2787 $data =~ s/\
215 2203         3198 local $_ = $data;
216 2203         4195 local ($Petal::NS) = $NameSpaces[$#NameSpaces];
217 2203         3415 local ($Petal::XI_NS) = $XI_NameSpaces[$#XI_NameSpaces];
218 2203         3238 local ($Petal::MT_NS) = $MT_NameSpaces[$#MT_NameSpaces];
219              
220 2203         16114 my $dont_skip = grep /^\Q$Petal::MT_NAME_CUR\E$/, @MT_Name_Cur;
221 2203 100       7216 $Canonicalizer->Text() if ($dont_skip);
222             }
223              
224              
225             sub generate_events_comment
226             {
227 13     13 0 50 my $skip = 1;
228 13 50       34 for (@MT_Name_Cur) { $_ eq $Petal::MT_NAME_CUR and $skip = 0 }
  33         99  
229              
230 13         27 my $data = shift;
231 13         45 local $_ = '';
232              
233 13         163 my $dont_skip = grep /^\Q$Petal::MT_NAME_CUR\E$/, @MT_Name_Cur;
234 13 50       105 $Canonicalizer->Text() if ($dont_skip);
235             }
236              
237              
238             1;
239              
240              
241             __END__