line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package XML::Writer::Simple; |
2
|
|
|
|
|
|
|
|
3
|
7
|
|
|
7
|
|
226711
|
use warnings; |
|
7
|
|
|
|
|
19
|
|
|
7
|
|
|
|
|
353
|
|
4
|
7
|
|
|
7
|
|
39
|
use strict; |
|
7
|
|
|
|
|
20
|
|
|
7
|
|
|
|
|
254
|
|
5
|
7
|
|
|
7
|
|
37
|
use Exporter (); |
|
7
|
|
|
|
|
22
|
|
|
7
|
|
|
|
|
154
|
|
6
|
7
|
|
|
7
|
|
42
|
use vars qw/@ISA @EXPORT/; |
|
7
|
|
|
|
|
34
|
|
|
7
|
|
|
|
|
471
|
|
7
|
7
|
|
|
7
|
|
11959
|
use XML::DT; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
use XML::DTDParser qw/ParseDTDFile/; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=encoding utf-8 |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 NAME |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
XML::Writer::Simple - Create XML files easily! |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=cut |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our $VERSION = '0.09'; |
19
|
|
|
|
|
|
|
@ISA = qw/Exporter/; |
20
|
|
|
|
|
|
|
@EXPORT = (qw/powertag xml_header quote_entities/); |
21
|
|
|
|
|
|
|
our %PTAGS = (); |
22
|
|
|
|
|
|
|
our $MODULENAME = "XML::Writer::Simple"; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
our $IS_HTML = 0; |
25
|
|
|
|
|
|
|
our %TAG_SET = ( |
26
|
|
|
|
|
|
|
html => { |
27
|
|
|
|
|
|
|
tags => [qw.a abbr acronym address area |
28
|
|
|
|
|
|
|
b base bdo big blockquote body br button |
29
|
|
|
|
|
|
|
caption cite code col colgroup |
30
|
|
|
|
|
|
|
dd del dfn div dl dt |
31
|
|
|
|
|
|
|
em |
32
|
|
|
|
|
|
|
fieldset form frame frameset |
33
|
|
|
|
|
|
|
h1 h2 h3 h4 h5 h6 head hr html |
34
|
|
|
|
|
|
|
i iframe img input ins |
35
|
|
|
|
|
|
|
kbd |
36
|
|
|
|
|
|
|
label legend li link |
37
|
|
|
|
|
|
|
map meta |
38
|
|
|
|
|
|
|
noframes noscript |
39
|
|
|
|
|
|
|
object ol optgroup option |
40
|
|
|
|
|
|
|
p param pre |
41
|
|
|
|
|
|
|
q |
42
|
|
|
|
|
|
|
samp script select small span strong style sub sup |
43
|
|
|
|
|
|
|
table tbody td textarea tfoot th thead title Tr tt |
44
|
|
|
|
|
|
|
u ul var.] |
45
|
|
|
|
|
|
|
}, |
46
|
|
|
|
|
|
|
); |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=head1 SYNOPSIS |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
use XML::Writer::Simple dtd => "file.dtd"; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
print xml_header(encoding => 'iso-8859-1'); |
53
|
|
|
|
|
|
|
print para("foo",b("bar"),"zbr"); |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# if you want CGI but you do not want CGI :) |
57
|
|
|
|
|
|
|
use XML::Writer::Simple ':html'; |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=head1 USAGE |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
This module takes some ideas from CGI to make easier the life for |
62
|
|
|
|
|
|
|
those who need to generated XML code. You can use the module in three |
63
|
|
|
|
|
|
|
flavours (or combine them): |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=over 4 |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=item tags |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
When importing the module you can specify the tags you will be using: |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
use XML::Writer::Simple tags => [qw/p b i tt/]; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
print p("Hey, ",b("you"),"! ", i("Yes ", b("you"))); |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
that will generate |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
Hey you! Yes you |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=item dtd |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
You can supply a DTD, that will be analyzed, and the tags used: |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
use XML::Writer::Simple dtd => "tmx.dtd"; |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
print tu(seg("foo"),seg("bar")); |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=item xml |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
You can supply an XML (or a reference to a list of XML files). They |
90
|
|
|
|
|
|
|
will be parsed, and the tags used: |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
use XML::Writer::Simple xml => "foo.xml"; |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
print foo("bar"); |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=item partial |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
You can supply an 'partial' key, to generate prototypes for partial tags |
99
|
|
|
|
|
|
|
construction. For instance: |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
use XML::Writer::Simple tags => qw/foo bar/, partial => 1; |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
print start_foo; |
104
|
|
|
|
|
|
|
print ... |
105
|
|
|
|
|
|
|
print end_foo; |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=back |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
You can also use tagsets, where sets of tags from a well known format |
110
|
|
|
|
|
|
|
are imported. For example, to use HTML: |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
use XML::Writer::Simple ':html'; |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=head1 EXPORT |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
This module export one function for each element at the dtd or xml |
117
|
|
|
|
|
|
|
file you are using. See below for details. |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=head1 FUNCTIONS |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=head2 import |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
Used when you 'use' the module, should not be used directly. |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=head2 xml_header |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
This function returns the xml header string, without encoding |
128
|
|
|
|
|
|
|
definition, with a trailing new line. Default XML encoding should |
129
|
|
|
|
|
|
|
be UTF-8, by the way. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
You can force an encoding passing it as argument: |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
print xml_header(encoding=>'iso-8859-1'); |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=head2 powertag |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
Used to specify a powertag. For instance: |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
powertag("ul","li"); |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
ul_li([qw/foo bar zbr ugh/]); |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
will generate |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
foo |
147
|
|
|
|
|
|
|
bar |
148
|
|
|
|
|
|
|
zbr |
149
|
|
|
|
|
|
|
ugh |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
You can also supply this information when loading the module, with |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
use XML::Writer::Simple powertags=>["ul_li","ol_li"]; |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
Powertags support three level tags as well: |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
use XML::Writer::Simple powertags=>["table_tr_td"]; |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
print table_tr_td(['a','b','c'],['d','e','f']); |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=head2 quote_entities |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
To use the special characters C<< < >>, C<< > >> and C<< & >> on your PCDATA content you need |
165
|
|
|
|
|
|
|
to protect them. You can either do that yourself or call this function. |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
print f(quote_entities("a < b")); |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=cut |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub xml_header { |
172
|
|
|
|
|
|
|
my %ops = @_; |
173
|
|
|
|
|
|
|
my $encoding = ""; |
174
|
|
|
|
|
|
|
$encoding =" encoding=\"$ops{encoding}\"" if exists $ops{encoding}; |
175
|
|
|
|
|
|
|
return "\n"; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
sub powertag { |
179
|
|
|
|
|
|
|
my $nfunc = join("_", @_); |
180
|
|
|
|
|
|
|
$PTAGS{$nfunc}=[@_]; |
181
|
|
|
|
|
|
|
push @EXPORT, $nfunc; |
182
|
|
|
|
|
|
|
XML::Writer::Simple->export_to_level(1, $MODULENAME, $nfunc); |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub _xml_from { |
186
|
|
|
|
|
|
|
my ($tag, $attrs, @body) = @_; |
187
|
|
|
|
|
|
|
return (ref($body[0]) eq "ARRAY")? |
188
|
|
|
|
|
|
|
join("", map{ _toxml($tag, $attrs, $_) } @{$body[0]}) |
189
|
|
|
|
|
|
|
:_toxml($tag, $attrs, join("", @body)); |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub _clean_attrs { |
193
|
|
|
|
|
|
|
my $attrs = shift; |
194
|
|
|
|
|
|
|
for (keys %$attrs) { |
195
|
|
|
|
|
|
|
if (m!^-!) { |
196
|
|
|
|
|
|
|
$attrs->{$'}=$attrs->{$_}; |
197
|
|
|
|
|
|
|
delete($attrs->{$_}); |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
return $attrs; |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
sub _toxml { |
204
|
|
|
|
|
|
|
my ($tag,$attr,$contents) = @_; |
205
|
|
|
|
|
|
|
if (defined($contents) && $contents ne "") { |
206
|
|
|
|
|
|
|
return _start_tag($tag,$attr) . $contents . _close_tag($tag); |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
else { |
209
|
|
|
|
|
|
|
return _empty_tag($tag,$attr); |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
sub _go_down { |
214
|
|
|
|
|
|
|
my ($tags, @values) = @_; |
215
|
|
|
|
|
|
|
my $tag = shift @$tags; |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
if (@$tags) { |
218
|
|
|
|
|
|
|
join("", |
219
|
|
|
|
|
|
|
map { |
220
|
|
|
|
|
|
|
my $attrs = {}; |
221
|
|
|
|
|
|
|
if (ref($_->[0]) eq 'HASH') { |
222
|
|
|
|
|
|
|
$attrs = _clean_attrs(shift @$_); |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
_xml_from($tag,$attrs,_go_down([@$tags],@$_)) } ### REALLY NEED TO COPY |
225
|
|
|
|
|
|
|
@values) |
226
|
|
|
|
|
|
|
} else { |
227
|
|
|
|
|
|
|
join("", |
228
|
|
|
|
|
|
|
map { _xml_from($tag,{},$_) } @values) |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub AUTOLOAD { |
233
|
|
|
|
|
|
|
my $attrs = {}; |
234
|
|
|
|
|
|
|
my $tag = our $AUTOLOAD; |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
$tag =~ s!${MODULENAME}::!!; |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
$attrs = shift if ref($_[0]) eq "HASH"; |
239
|
|
|
|
|
|
|
$attrs = _clean_attrs($attrs); |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
if (exists($PTAGS{$tag})) { |
242
|
|
|
|
|
|
|
my @tags = @{$PTAGS{$tag}}; |
243
|
|
|
|
|
|
|
my $toptag = shift @tags; |
244
|
|
|
|
|
|
|
return _xml_from($toptag, $attrs, |
245
|
|
|
|
|
|
|
_go_down(\@tags, @_)); |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
else { |
248
|
|
|
|
|
|
|
if ($tag =~ m/^end_(.*)$/) { |
249
|
|
|
|
|
|
|
return _close_tag($1)."\n"; |
250
|
|
|
|
|
|
|
} |
251
|
|
|
|
|
|
|
elsif ($tag =~ m/^start_(.*)$/) { |
252
|
|
|
|
|
|
|
return _start_tag($1, $attrs)."\n"; |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
else { |
255
|
|
|
|
|
|
|
return _xml_from($tag,$attrs,@_); |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
sub quote_entities { |
261
|
|
|
|
|
|
|
my $s = shift; |
262
|
|
|
|
|
|
|
$s =~ s/&/&/g; |
263
|
|
|
|
|
|
|
$s =~ s/</g; |
264
|
|
|
|
|
|
|
$s =~ s/>/>/g; |
265
|
|
|
|
|
|
|
return $s; |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
sub _quote_attr { |
269
|
|
|
|
|
|
|
my $s = shift; |
270
|
|
|
|
|
|
|
$s =~ s/&/&/g; |
271
|
|
|
|
|
|
|
$s =~ s/"/"/g; |
272
|
|
|
|
|
|
|
return $s; |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub _attributes { |
276
|
|
|
|
|
|
|
my $attr = shift; |
277
|
|
|
|
|
|
|
return join(" ", map { "$_=\"" . _quote_attr($attr->{$_}) . "\""} keys %$attr); |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
sub _start_tag { |
281
|
|
|
|
|
|
|
my ($tag, $attr) = @_; |
282
|
|
|
|
|
|
|
$tag = "tr" if $tag eq "Tr" && $IS_HTML; |
283
|
|
|
|
|
|
|
$attr = _attributes($attr); |
284
|
|
|
|
|
|
|
if ($attr) { |
285
|
|
|
|
|
|
|
return "<$tag $attr>" |
286
|
|
|
|
|
|
|
} else { |
287
|
|
|
|
|
|
|
return "<$tag>" |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
sub _empty_tag { |
292
|
|
|
|
|
|
|
my ($tag, $attr) = @_; |
293
|
|
|
|
|
|
|
$tag = "tr" if $tag eq "Tr" && $IS_HTML; |
294
|
|
|
|
|
|
|
$attr = _attributes($attr); |
295
|
|
|
|
|
|
|
if ($attr) { |
296
|
|
|
|
|
|
|
return "<$tag $attr/>" |
297
|
|
|
|
|
|
|
} else { |
298
|
|
|
|
|
|
|
return "<$tag/>" |
299
|
|
|
|
|
|
|
} |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
sub _close_tag { |
303
|
|
|
|
|
|
|
my $tag = shift; |
304
|
|
|
|
|
|
|
$tag = "tr" if $tag eq "Tr" && $IS_HTML; |
305
|
|
|
|
|
|
|
return "$tag>"; |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
sub import { |
310
|
|
|
|
|
|
|
my $class = shift; |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
my @tags; |
313
|
|
|
|
|
|
|
my @ptags; |
314
|
|
|
|
|
|
|
while ($_[0] && $_[0] =~ m!^:(.*)$!) { |
315
|
|
|
|
|
|
|
shift; |
316
|
|
|
|
|
|
|
my $pack = $1; |
317
|
|
|
|
|
|
|
$IS_HTML = 1 if $pack eq "html"; |
318
|
|
|
|
|
|
|
if (exists($TAG_SET{$pack})) { |
319
|
|
|
|
|
|
|
push @tags => exists $TAG_SET{$pack}{tags} ? @{$TAG_SET{$pack}{tags}} : (); |
320
|
|
|
|
|
|
|
push @ptags => exists $TAG_SET{$pack}{ptags} ? @{$TAG_SET{$pack}{ptags}} : (); |
321
|
|
|
|
|
|
|
} else { |
322
|
|
|
|
|
|
|
die "XML::Writer::Simple - Unknown tagset :$pack\n"; |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
my %opts = @_; |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
if (exists($opts{tags})) { |
329
|
|
|
|
|
|
|
if (ref($opts{tags}) eq "ARRAY") { |
330
|
|
|
|
|
|
|
push @tags => @{$opts{tags}}; |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
if (exists($opts{xml})) { |
335
|
|
|
|
|
|
|
my @xmls = (ref($opts{xml}) eq "ARRAY")?@{$opts{xml}}:($opts{xml}); |
336
|
|
|
|
|
|
|
my $tags; |
337
|
|
|
|
|
|
|
for my $xml (@xmls) { |
338
|
|
|
|
|
|
|
dt($xml, -default => sub { $tags->{$q}++ }); |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
push @tags => keys %$tags; |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
if (exists($opts{dtd})) { |
344
|
|
|
|
|
|
|
my $DTD = ParseDTDFile($opts{dtd}); |
345
|
|
|
|
|
|
|
push @tags => keys %$DTD; |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
push @EXPORT => @tags; |
349
|
|
|
|
|
|
|
if (exists($opts{partial})) { |
350
|
|
|
|
|
|
|
push @EXPORT => map { "start_$_" } @tags; |
351
|
|
|
|
|
|
|
push @EXPORT => map { "end_$_" } @tags; |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
if (@ptags || exists($opts{powertags})) { |
355
|
|
|
|
|
|
|
push @ptags => @{$opts{powertags}} if exists $opts{powertags}; |
356
|
|
|
|
|
|
|
@PTAGS{@ptags} = map { [split/_/] } @ptags; |
357
|
|
|
|
|
|
|
push @EXPORT => @ptags; |
358
|
|
|
|
|
|
|
} |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
XML::Writer::Simple->export_to_level(1, $class, @EXPORT); |
361
|
|
|
|
|
|
|
} |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
=head1 AUTHOR |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
Alberto Simões, C<< >> |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
=head1 BUGS |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
Please report any bugs or feature requests to |
370
|
|
|
|
|
|
|
C, or through the web interface at |
371
|
|
|
|
|
|
|
L. |
372
|
|
|
|
|
|
|
I will be notified, and then you'll automatically be notified of progress on |
373
|
|
|
|
|
|
|
your bug as I make changes. |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
Copyright 1999-2012 Project Natura. |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
380
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
=cut |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
1; # End of XML::Writer::Simple |