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