File Coverage

blib/lib/XML/MinWriter.pm
Criterion Covered Total %
statement 113 127 88.9
branch 47 50 94.0
condition 10 15 66.6
subroutine 15 19 78.9
pod 13 15 86.6
total 198 226 87.6


line stmt bran cond sub pod time code
1             package XML::MinWriter;
2            
3 1     1   1095 use strict;
  1         1  
  1         47  
4 1     1   5 use warnings;
  1         2  
  1         29  
5            
6 1     1   20 use Carp;
  1         2  
  1         73  
7            
8             require Exporter;
9 1     1   964 use XML::Writer;
  1         14574  
  1         1361  
10            
11             our @ISA = qw(Exporter XML::Writer);
12            
13             our @EXPORT_OK = qw();
14            
15             our @EXPORT = qw();
16            
17             our $VERSION = '0.06';
18            
19             sub new {
20 15     15 1 137988 my $class = shift;
21 15         79 my $self = $class->SUPER::new(@_);
22            
23 15         2689 $self->{PYX_TYPE} = '';
24 15         31 $self->{PYX_TAG} = '';
25 15         33 $self->{PYX_ATTR} = [];
26            
27 15         52 bless $self, $class; # reconsecrate
28             }
29            
30 4     4 1 6 sub xmlDecl { my $self = shift; $self->flush_pyx; $self->SUPER::xmlDecl(@_); }
  4         12  
  4         24  
31 3     3 1 5 sub doctype { my $self = shift; $self->flush_pyx; $self->SUPER::doctype(@_); }
  3         6  
  3         16  
32 4     4 1 5 sub comment { my $self = shift; $self->flush_pyx; $self->SUPER::comment(@_); }
  4         16  
  4         19  
33 3     3 1 5 sub pi { my $self = shift; $self->flush_pyx; $self->SUPER::pi(@_); }
  3         16  
  3         15  
34 3     3 1 23 sub startTag { my $self = shift; $self->flush_pyx; $self->SUPER::startTag(@_); }
  3         8  
  3         13  
35 0     0 1 0 sub emptyTag { my $self = shift; $self->flush_pyx; $self->SUPER::emptyTag(@_); }
  0         0  
  0         0  
36 62     62 1 144 sub endTag { my $self = shift; $self->flush_pyx; $self->SUPER::endTag(@_); }
  62         106  
  62         224  
37 22     22 1 25 sub characters { my $self = shift; $self->flush_pyx; $self->SUPER::characters(@_); }
  22         68  
  22         81  
38 0     0 1 0 sub raw { my $self = shift; $self->flush_pyx; $self->SUPER::raw(@_); }
  0         0  
  0         0  
39 0     0 1 0 sub cdata { my $self = shift; $self->flush_pyx; $self->SUPER::cdata(@_); }
  0         0  
  0         0  
40 0     0 1 0 sub dataElement { my $self = shift; $self->flush_pyx; $self->SUPER::dataElement(@_); }
  0         0  
  0         0  
41 14     14 1 404 sub end { my $self = shift; $self->flush_pyx; $self->SUPER::end(@_); }
  14         29  
  14         51  
42            
43             sub write_pyx {
44 148     148 0 2764 my $self = shift;
45            
46 148         155 my @inlist;
47 148         338 for (@_) {
48 185         520 push @inlist, split m{\n}xms;
49             }
50            
51 148         244 LOOP1: for my $instr (@inlist) {
52 191 100       562 if ($instr eq '') {
53 2         4 next LOOP1;
54             }
55            
56 189         283 my $code = substr($instr, 0, 1);
57 189         253 my $text = substr($instr, 1);
58            
59 189         280 $text =~ s{\\(.)}{
60 30 100       137 $1 eq '\\' ? "\\" :
    50          
    100          
61             $1 eq 'n' ? "\n" :
62             $1 eq 't' ? "\t" :
63             "\\".$1}xmsge;
64            
65 189 100       664 if ($code eq '(') {
    100          
    100          
    100          
    100          
    100          
    100          
66 59         122 $self->flush_pyx;
67 59         105 $self->{PYX_TYPE} = '(';
68 59         89 $self->{PYX_TAG} = $text;
69 59         292 $self->{PYX_ATTR} = [];
70             }
71             elsif ($code eq 'A') {
72 27         149 my ($key, $val) = $text =~ m{\A (\S+) \s+ (.*) \z}xms;
73 27 100 66     128 unless (defined($key) and defined($val)) {
74 1         167 carp "Can't parse (key, val) [code = 'A'] in '$text' in write_pyx()";
75 1         48 next LOOP1;
76             }
77 26         28 push @{$self->{PYX_ATTR}}, $key, $val;
  26         113  
78             }
79             elsif ($code eq '?') {
80 10         52 my ($intro, $def) = $text =~ m{\A (\S+) \s+ (.*) \z}xms;
81 10 100 66     53 unless (defined($intro) and defined($def)) {
82 1         146 carp "Can't parse (intro, def) [code = '?'] in '$text' in write_pyx()";
83 1         78 next LOOP1;
84             }
85            
86 9 100 66     44 if ($intro =~ m{\A xml}xmsi and $intro !~ m{\A xml-stylesheet \z}xmsi) {
87 6         11 my ($version, $encoding, $standalone);
88 6         9 my $data = $def;
89 6         51 while (my ($key, $val, $rest) = $data =~ m{\A (\S+) \s* = \s* ["']([^"']+)["'] \s* (.*) \z}xms) {
90 7 100       31 if ($key =~ m{\A version \z}xmsi) { $version = $val; }
  2 100       3  
    50          
91 4         5 elsif ($key =~ m{\A encoding \z}xmsi) { $encoding = $val; }
92 0         0 elsif ($key =~ m{\A standalone \z}xmsi) { $standalone = $val; }
93             else {
94 1         131 carp "Found invalid XML-Declaration (key = '$key') in (intro = '$intro', def = '$def') in write_pyx()";
95 1         59 next LOOP1;
96             }
97 6 100       21 unless (defined $version) { $version = '1.0'; }
  3         7  
98 6 100       19 unless ($version eq '1.0') {
99 1         131 carp "Found version other than 1.0 ('$version') in (intro = '$intro', def = '$def') in write_pyx()";
100 1         49 next LOOP1;
101             }
102 5         22 $data = $rest;
103             }
104 4         17 $self->xmlDecl($encoding, $standalone);
105             }
106             else {
107 3         13 $self->pi($intro, $def);
108             }
109             }
110             elsif ($code eq '!') {
111 7         31 my ($intro, $def) = $text =~ m{\A (\S+) \s+ (.*) \z}xms;
112 7 100 66     34 unless (defined($intro) and defined($def)) {
113 1         125 carp "Can't parse (intro, def) [code = '!'] in '$text' in write_pyx()";
114 1         41 next LOOP1;
115             }
116            
117 6 100       26 if ($def =~ m{\A PUBLIC}xmsi) {
    100          
118 4         18 my ($public, $system) = $def =~ m{\A PUBLIC \s+ ["']([^"']+)["'] \s+ ["']([^"']+)["'] \s* \z}xmsi;
119 4 100 66     18 unless (defined($public) and defined($system)) {
120 1         134 carp "Can't parse DOCTYPE PUBLIC in (intro = '$intro', def = '$def') in write_pyx()";
121 1         44 next LOOP1;
122             }
123 3         10 $self->doctype($intro, $public, $system);
124             }
125             elsif ($def =~ m{\A SYSTEM}xmsi) {
126 1         5 my ($system) = $def =~ m{\A SYSTEM \s+ ["']([^"']+)["'] \s* \z}xmsi;
127 1 50       6 unless (defined($system)) {
128 1         131 carp "Can't parse DOCTYPE SYSTEM in (intro = '$intro', def = '$def') in write_pyx()";
129 1         42 next LOOP1;
130             }
131 0         0 $self->doctype($intro, undef, $system);
132             }
133             else {
134 1         134 carp "Can't find neither PUBLIC nor SYSTEM in DOCTYPE (intro = '$intro', def = '$def') in write_pyx()";
135 1         46 next LOOP1;
136             }
137             }
138 59         128 elsif ($code eq ')') { $self->endTag($text); }
139 22         53 elsif ($code eq '-') { $self->characters($text); }
140 4         12 elsif ($code eq '#') { $self->comment($text); }
141             else {
142 1         128 carp "Invalid code = '$code' in write_pyx()";
143 1         43 next LOOP1;
144             }
145             }
146             }
147            
148             sub flush_pyx {
149 174     174 0 194 my $self = shift;
150            
151 174 100       430 if ($self->{PYX_TYPE} eq '(') {
152 59         87 $self->SUPER::startTag($self->{PYX_TAG}, @{$self->{PYX_ATTR}});
  59         214  
153             }
154            
155 174         3588 $self->{PYX_TYPE} = '';
156 174         263 $self->{PYX_TAG} = '';
157 174         347 $self->{PYX_ATTR} = [];
158             }
159            
160             1;
161            
162             __END__