| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package PYX::XMLNorm; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | # Pragmas. | 
| 4 | 6 |  |  | 6 |  | 155261 | use strict; | 
|  | 6 |  |  |  |  | 14 |  | 
|  | 6 |  |  |  |  | 151 |  | 
| 5 | 6 |  |  | 6 |  | 29 | use warnings; | 
|  | 6 |  |  |  |  | 12 |  | 
|  | 6 |  |  |  |  | 178 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | # Modules. | 
| 8 | 6 |  |  | 6 |  | 2684 | use Class::Utils qw(set_params); | 
|  | 6 |  |  |  |  | 94703 |  | 
|  | 6 |  |  |  |  | 196 |  | 
| 9 | 6 |  |  | 6 |  | 219 | use Error::Pure qw(err); | 
|  | 6 |  |  |  |  | 13 |  | 
|  | 6 |  |  |  |  | 234 |  | 
| 10 | 6 |  |  | 6 |  | 4284 | use PYX qw(end_element); | 
|  | 6 |  |  |  |  | 60401 |  | 
|  | 6 |  |  |  |  | 124 |  | 
| 11 | 6 |  |  | 6 |  | 5390 | use PYX::Parser; | 
|  | 6 |  |  |  |  | 8169 |  | 
|  | 6 |  |  |  |  | 6576 |  | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | # Version. | 
| 14 |  |  |  |  |  |  | our $VERSION = 0.04; | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | # Constructor. | 
| 17 |  |  |  |  |  |  | sub new { | 
| 18 | 7 |  |  | 7 | 1 | 5713 | my ($class, @params) = @_; | 
| 19 | 7 |  |  |  |  | 19 | my $self = bless {}, $class; | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | # Flush stack on finalization. | 
| 22 | 7 |  |  |  |  | 31 | $self->{'flush_stack'} = 0; | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | # Output handler. | 
| 25 | 7 |  |  |  |  | 17 | $self->{'output_handler'} = \*STDOUT; | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | # XML normalization rules. | 
| 28 | 7 |  |  |  |  | 19 | $self->{'rules'} = {}; | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | # Process params. | 
| 31 | 7 |  |  |  |  | 28 | set_params($self, @params); | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | # Check to rules. | 
| 34 | 5 | 100 |  |  |  | 52 | if (! keys %{$self->{'rules'}}) { | 
|  | 5 |  |  |  |  | 29 |  | 
| 35 | 1 |  |  |  |  | 4 | err 'Cannot exist XML normalization rules.'; | 
| 36 |  |  |  |  |  |  | } | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | # PYX::Parser object. | 
| 39 |  |  |  |  |  |  | $self->{'pyx_parser'} = PYX::Parser->new( | 
| 40 |  |  |  |  |  |  | 'callbacks' => { | 
| 41 |  |  |  |  |  |  | 'data' => \&_end_element_simple, | 
| 42 |  |  |  |  |  |  | 'end_element' => \&_end_element, | 
| 43 |  |  |  |  |  |  | 'final' => \&_final, | 
| 44 |  |  |  |  |  |  | 'start_element' => \&_start_element, | 
| 45 |  |  |  |  |  |  | }, | 
| 46 |  |  |  |  |  |  | 'non_parser_options' => { | 
| 47 |  |  |  |  |  |  | 'flush_stack' => $self->{'flush_stack'}, | 
| 48 |  |  |  |  |  |  | 'rules' => $self->{'rules'}, | 
| 49 |  |  |  |  |  |  | 'stack' => [], | 
| 50 |  |  |  |  |  |  | }, | 
| 51 | 4 |  |  |  |  | 81 | 'output_handler' => $self->{'output_handler'}, | 
| 52 |  |  |  |  |  |  | 'output_rewrite' => 1, | 
| 53 |  |  |  |  |  |  | ); | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | # Object. | 
| 56 | 4 |  |  |  |  | 220 | return $self; | 
| 57 |  |  |  |  |  |  | } | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | # Parse pyx text or array of pyx text. | 
| 60 |  |  |  |  |  |  | sub parse { | 
| 61 | 1 |  |  | 1 | 1 | 1242 | my ($self, $pyx, $out) = @_; | 
| 62 | 1 |  |  |  |  | 6 | $self->{'pyx_parser'}->parse($pyx, $out); | 
| 63 | 1 |  |  |  |  | 4 | return; | 
| 64 |  |  |  |  |  |  | } | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  | # Parse file with pyx text. | 
| 67 |  |  |  |  |  |  | sub parse_file { | 
| 68 | 7 |  |  | 7 | 1 | 10445 | my ($self, $file) = @_; | 
| 69 | 7 |  |  |  |  | 26 | $self->{'pyx_parser'}->parse_file($file); | 
| 70 | 7 |  |  |  |  | 93 | return; | 
| 71 |  |  |  |  |  |  | } | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | # Parse from handler. | 
| 74 |  |  |  |  |  |  | sub parse_handler { | 
| 75 | 1 |  |  | 1 | 1 | 1118 | my ($self, $input_file_handler, $out) = @_; | 
| 76 | 1 |  |  |  |  | 6 | $self->{'pyx_parser'}->parse_handler($input_file_handler, $out); | 
| 77 | 1 |  |  |  |  | 3 | return; | 
| 78 |  |  |  |  |  |  | } | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | # Process start of element. | 
| 81 |  |  |  |  |  |  | sub _start_element { | 
| 82 | 55 |  |  | 55 |  | 1693 | my ($pyx_parser, $tag) = @_; | 
| 83 | 55 |  |  |  |  | 83 | my $out = $pyx_parser->{'output_handler'}; | 
| 84 | 55 |  |  |  |  | 88 | my $rules = $pyx_parser->{'non_parser_options'}->{'rules'}; | 
| 85 | 55 |  |  |  |  | 82 | my $stack = $pyx_parser->{'non_parser_options'}->{'stack'}; | 
| 86 | 55 | 50 |  |  |  | 141 | if (exists $rules->{'*'}) { | 
| 87 | 55 |  |  |  |  | 63 | foreach my $tmp (@{$rules->{'*'}}) { | 
|  | 55 |  |  |  |  | 119 |  | 
| 88 | 275 | 100 | 100 |  |  | 417 | if (@{$stack} > 0 && lc($stack->[-1]) eq $tmp) { | 
|  | 275 |  |  |  |  | 1276 |  | 
| 89 | 15 |  |  |  |  | 18 | print {$out} end_element(pop @{$stack}), "\n"; | 
|  | 15 |  |  |  |  | 27 |  | 
|  | 15 |  |  |  |  | 47 |  | 
| 90 |  |  |  |  |  |  | } | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  | } | 
| 93 | 55 | 100 |  |  |  | 201 | if (exists $rules->{lc($tag)}) { | 
| 94 | 21 |  |  |  |  | 26 | foreach my $tmp (@{$rules->{lc($tag)}}) { | 
|  | 21 |  |  |  |  | 51 |  | 
| 95 | 34 | 100 | 100 |  |  | 62 | if (@{$stack} > 0 && lc($stack->[-1]) eq $tmp) { | 
|  | 34 |  |  |  |  | 166 |  | 
| 96 | 7 |  |  |  |  | 9 | print {$out} end_element(pop @{$stack}), "\n"; | 
|  | 7 |  |  |  |  | 10 |  | 
|  | 7 |  |  |  |  | 19 |  | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  | } | 
| 99 |  |  |  |  |  |  | } | 
| 100 | 55 |  |  |  |  | 124 | push @{$stack}, $tag; | 
|  | 55 |  |  |  |  | 107 |  | 
| 101 | 55 |  |  |  |  | 75 | print {$out} $pyx_parser->line, "\n"; | 
|  | 55 |  |  |  |  | 162 |  | 
| 102 | 55 |  |  |  |  | 1131 | return; | 
| 103 |  |  |  |  |  |  | } | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | # Add implicit end_element. | 
| 106 |  |  |  |  |  |  | sub _end_element_simple { | 
| 107 | 11 |  |  | 11 |  | 245 | my $pyx_parser = shift; | 
| 108 | 11 |  |  |  |  | 20 | my $rules = $pyx_parser->{'non_parser_options'}->{'rules'}; | 
| 109 | 11 |  |  |  |  | 19 | my $stack = $pyx_parser->{'non_parser_options'}->{'stack'}; | 
| 110 | 11 |  |  |  |  | 14 | my $out = $pyx_parser->{'output_handler'}; | 
| 111 | 11 | 50 |  |  |  | 26 | if (exists $rules->{'*'}) { | 
| 112 | 11 |  |  |  |  | 12 | foreach my $tmp (@{$rules->{'*'}}) { | 
|  | 11 |  |  |  |  | 23 |  | 
| 113 | 55 | 100 | 100 |  |  | 86 | if (@{$stack} && lc $stack->[-1] eq $tmp) { | 
|  | 55 |  |  |  |  | 234 |  | 
| 114 | 2 |  |  |  |  | 3 | print {$out} end_element(pop @{$stack}), "\n"; | 
|  | 2 |  |  |  |  | 5 |  | 
|  | 2 |  |  |  |  | 7 |  | 
| 115 |  |  |  |  |  |  | } | 
| 116 |  |  |  |  |  |  | } | 
| 117 |  |  |  |  |  |  | } | 
| 118 | 11 |  |  |  |  | 14 | print {$out} $pyx_parser->line, "\n"; | 
|  | 11 |  |  |  |  | 31 |  | 
| 119 | 11 |  |  |  |  | 138 | return; | 
| 120 |  |  |  |  |  |  | } | 
| 121 |  |  |  |  |  |  |  | 
| 122 |  |  |  |  |  |  | # Process end of element | 
| 123 |  |  |  |  |  |  | sub _end_element { | 
| 124 | 14 |  |  | 14 |  | 312 | my ($pyx_parser, $tag) = @_; | 
| 125 | 14 |  |  |  |  | 21 | my $out = $pyx_parser->{'output_handler'}; | 
| 126 | 14 |  |  |  |  | 33 | my $rules = $pyx_parser->{'non_parser_options'}->{'rules'}; | 
| 127 | 14 |  |  |  |  | 21 | my $stack = $pyx_parser->{'non_parser_options'}->{'stack'}; | 
| 128 | 14 | 50 |  |  |  | 93 | if (exists $rules->{'*'}) { | 
| 129 | 14 |  |  |  |  | 18 | foreach my $tmp (@{$rules->{'*'}}) { | 
|  | 14 |  |  |  |  | 35 |  | 
| 130 | 70 | 100 | 100 |  |  | 444 | if (lc($tag) ne $tmp && lc($stack->[-1]) eq $tmp) { | 
| 131 | 7 |  |  |  |  | 11 | print {$out} end_element(pop @{$stack}), "\n"; | 
|  | 7 |  |  |  |  | 12 |  | 
|  | 7 |  |  |  |  | 22 |  | 
| 132 |  |  |  |  |  |  | } | 
| 133 |  |  |  |  |  |  | } | 
| 134 |  |  |  |  |  |  | } | 
| 135 |  |  |  |  |  |  | # XXX Myslim, ze tenhle blok je spatne. | 
| 136 | 14 | 100 |  |  |  | 40 | if (exists $rules->{$tag}) { | 
| 137 | 8 |  |  |  |  | 13 | foreach my $tmp (@{$rules->{$tag}}) { | 
|  | 8 |  |  |  |  | 19 |  | 
| 138 | 11 | 100 | 66 |  |  | 88 | if (lc($tag) ne $tmp && lc($stack->[-1]) eq $tmp) { | 
| 139 | 10 |  |  |  |  | 14 | print {$out} end_element(pop @{$stack}), "\n"; | 
|  | 10 |  |  |  |  | 18 |  | 
|  | 10 |  |  |  |  | 29 |  | 
| 140 |  |  |  |  |  |  | } | 
| 141 |  |  |  |  |  |  | } | 
| 142 |  |  |  |  |  |  | } | 
| 143 | 14 | 50 |  |  |  | 120 | if (lc($stack->[-1]) eq lc($tag)) { | 
| 144 | 14 |  |  |  |  | 17 | pop @{$stack}; | 
|  | 14 |  |  |  |  | 25 |  | 
| 145 |  |  |  |  |  |  | } | 
| 146 | 14 |  |  |  |  | 23 | print {$out} $pyx_parser->line, "\n"; | 
|  | 14 |  |  |  |  | 39 |  | 
| 147 | 14 |  |  |  |  | 181 | return; | 
| 148 |  |  |  |  |  |  | } | 
| 149 |  |  |  |  |  |  |  | 
| 150 |  |  |  |  |  |  | # Process final. | 
| 151 |  |  |  |  |  |  | sub _final { | 
| 152 | 9 |  |  | 9 |  | 105 | my $pyx_parser = shift; | 
| 153 | 9 |  |  |  |  | 45 | my $stack = $pyx_parser->{'non_parser_options'}->{'stack'}; | 
| 154 | 9 |  |  |  |  | 18 | my $out = $pyx_parser->{'output_handler'}; | 
| 155 | 9 | 50 |  |  |  | 11 | if (@{$stack} > 0) { | 
|  | 9 |  |  |  |  | 33 |  | 
| 156 |  |  |  |  |  |  |  | 
| 157 |  |  |  |  |  |  | # If set, than flush stack. | 
| 158 | 0 | 0 |  |  |  | 0 | if ($pyx_parser->{'non_parser_options'}->{'flush_stack'}) { | 
| 159 | 0 |  |  |  |  | 0 | foreach my $tmp (reverse @{$stack}) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 160 | 0 |  |  |  |  | 0 | print {$out} end_element($tmp), "\n"; | 
|  | 0 |  |  |  |  | 0 |  | 
| 161 |  |  |  |  |  |  | } | 
| 162 |  |  |  |  |  |  | } | 
| 163 |  |  |  |  |  |  | } | 
| 164 | 9 |  |  |  |  | 21 | return; | 
| 165 |  |  |  |  |  |  | } | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | 1; | 
| 168 |  |  |  |  |  |  |  | 
| 169 |  |  |  |  |  |  | __END__ |