File Coverage

blib/lib/XML/TMX/Writer.pm
Criterion Covered Total %
statement 133 153 86.9
branch 33 62 53.2
condition 11 26 42.3
subroutine 16 16 100.0
pod 4 4 100.0
total 197 261 75.4


line stmt bran cond sub pod time code
1             package XML::TMX::Writer;
2             $XML::TMX::Writer::VERSION = '0.36';
3             # ABSTRACT: Perl extension for writing TMX files
4              
5 2     2   46290 use 5.010;
  2         6  
6 2     2   9 use warnings;
  2         4  
  2         40  
7 2     2   7 use strict;
  2         4  
  2         47  
8 2     2   10 use Exporter ();
  2         4  
  2         2776  
9              
10             our @ISA = 'Exporter';
11             our @EXPORT_OK = qw();
12              
13              
14             sub new {
15 1     1 1 465 my $proto = shift;
16 1   33     6 my $class = ref($proto) || $proto;
17 1         2 my %ops = @_;
18 1         3 my $self = { OUTPUT => \*STDOUT };
19 1 50 33     7 binmode $self->{OUTPUT}, ":utf8" unless exists $ops{-encoding} and $ops{-encoding} !~ /utf.?8/i;
20 1         2 bless($self, $class);
21 1         2 return($self);
22             }
23              
24              
25             sub start_tmx {
26 1     1 1 308 my $self = shift;
27 1         4 my %options = @_;
28 1         2 my %o;
29              
30 1         21 my @time = gmtime(time);
31 1         8 $o{'creationdate'} = sprintf("%d%02d%02dT%02d%02d%02dZ", $time[5]+1900,
32             $time[4]+1, $time[3], $time[2], $time[1], $time[0]);
33              
34 1   50     6 my $encoding = $options{encoding} || "UTF-8";
35              
36 1 50       5 if (defined($options{'-output'})) {
37 1         5 delete $self->{OUTPUT}; # because it is a glob
38 1 50       90 open $self->{OUTPUT}, ">", $options{'-output'}
39             or die "Cannot open file '$options{'-output'}': $!\n";
40             }
41              
42 1 50       8 if ($encoding =~ m!utf.?8!i) {
43 1         5 binmode $self->{OUTPUT}, ":utf8"
44             }
45 1         6 $self->_write("\n");
46              
47 1         3 my @valid_segtype = qw'block sentence paragraph phrase';
48 1 50 33     4 if(defined($options{SEGTYPE}) && grep { $_ eq $options{SEGTYPE} } @valid_segtype) {
  0         0  
49 0         0 $o{segtype} = $options{SEGTYPE};
50             } else {
51 1         2 $o{segtype} = 'sentence'
52             }
53              
54 1   50     5 $o{'creationtool'} = $options{tool} || 'XML::TMX::Writer';
55 1   33     4 $o{'creationtoolversion'} = $options{toolversion} || $XML::TMX::Writer::VERSION;
56 1   50     4 $o{'o-tmf'} = $options{srctmf} || 'plain text';
57 1   50     3 $o{'adminlang'} = $options{adminlang} || 'en';
58 1   50     4 $o{'srclang'} = $options{srclang} || 'en';
59 1   50     4 $o{'datatype'} = $options{datatype} || 'plaintext';
60              
61 1 50       5 defined($options{srcencoding}) and $o{'o-encoding'} = $options{srcencoding};
62 1 50       3 defined($options{id}) and $o{'creationid'} = $options{id};
63              
64 1         3 $self->_startTag(0, 'tmx', 'version' => 1.4)->_nl;
65 1         5 $self->_startTag(1, 'header', %o)->_nl;
66              
67 1 50       13 $self->_write_props(2, $options{'-prop'}) if defined $options{'-prop'};
68 1 50       7 $self->_write_notes(2, $options{'-note'}) if defined $options{'-note'};
69              
70 1         2 $self->_indent(1)->_endTag('header')->_nl;
71              
72 1         3 $self->_startTag(0,'body')->_nl->_nl;
73             }
74              
75             sub _write_props {
76 3     3   6 my ($self, $indent, $props) = @_;
77 3 50       7 return unless ref($props) eq "HASH";
78 3         10 for my $key (sort keys %$props) {
79 6 50       13 if (ref($props->{$key}) eq "ARRAY") {
80 0         0 for my $val (@{$props->{$key}}) {
  0         0  
81 0 0       0 if ($key eq "_") {
82 0         0 $self->_startTag($indent, 'prop');
83             } else {
84 0         0 $self->_startTag($indent, prop => (type => $key));
85             }
86 0         0 $self->_characters($val);
87 0         0 $self->_endTag('prop')->_nl;
88             }
89             } else {
90 6 50       11 if ($key eq "_") {
91 0         0 $self->_startTag($indent, 'prop');
92             } else {
93 6         9 $self->_startTag($indent, prop => (type => $key));
94             }
95 6         12 $self->_characters($props->{$key});
96 6         10 $self->_endTag('prop')->_nl;
97             }
98             }
99             }
100              
101             sub _write_notes {
102 3     3   4 my ($self, $indent, $notes) = @_;
103 3 50       8 return unless ref($notes) eq "ARRAY";
104 3         4 for my $p (@{$notes}) {
  3         4  
105 10         20 $self->_startTag($indent, 'note');
106 10         17 $self->_characters($p);
107 10         15 $self->_endTag('note')->_nl;
108             }
109             }
110              
111              
112             sub add_tu {
113 1     1 1 12 my $self = shift;
114 1         4 my %tuv = @_;
115 1         2 my %prop = ();
116 1         2 my @note = ();
117 1         1 my %opt;
118              
119 1         2 my $verbatim = 0;
120 1         1 my $cdata = 0;
121              
122 1 50       3 if (exists($tuv{-raw})) {
123             # value already includes tags, hopefully, at least!
124             # so we will not mess with it.
125 0         0 $self->_write($tuv{-raw});
126 0         0 return;
127             }
128              
129 1         2 for my $key (qw'id datatype segtype srclang creationid creationdate') {
130 6 100       11 if (exists($tuv{$key})) {
131 1         2 $opt{$key} = $tuv{$key};
132 1         2 delete $tuv{$key};
133             }
134             }
135 1 50       6 if (defined($tuv{srcencoding})) {
136 0         0 $opt{'o-encoding'} = $tuv{srcencoding};
137 0         0 delete $tuv{srcencoding};
138             }
139 1 50       2 $verbatim++ if defined $tuv{-verbatim};
140 1 50       3 delete $tuv{-verbatim} if exists $tuv{-verbatim};
141              
142 1 50       2 if (defined($tuv{"-prop"})) {
143 1         2 %prop = %{$tuv{"-prop"}};
  1         3  
144 1         2 delete $tuv{"-prop"};
145             }
146 1 50       5 if (defined($tuv{"-note"})) {
147 1         2 @note = @{$tuv{"-note"}};
  1         2  
148 1         2 delete $tuv{"-note"};
149             }
150 1 50       3 if (defined($tuv{"-n"})) {
151 0         0 $opt{id}=$tuv{"-n"};
152 0         0 delete $tuv{"-n"};
153             }
154              
155 1         3 $self->_startTag(0,'tu', %opt)->_nl;
156              
157             ### write the prop s problemas 23
158 1         2 $self->_write_props(3, \%prop);
159 1         3 $self->_write_notes(3, \@note);
160              
161 1         3 for my $lang (sort keys %tuv) {
162 2         3 my $cdata = 0;
163 2         5 $self->_startTag(1, 'tuv', 'xml:lang' => $lang);
164 2 100       6 if (ref($tuv{$lang}) eq "HASH") {
165 1 50       3 $cdata++ if defined($tuv{$lang}{-iscdata});
166 1 50       3 delete($tuv{$lang}{-iscdata}) if exists($tuv{$lang}{-iscdata});
167              
168 1 50       3 $self->_write_props(2, $tuv{$lang}{-prop}) if exists $tuv{$lang}{-prop};
169 1 50       4 $self->_write_notes(2, $tuv{$lang}{-note}) if exists $tuv{$lang}{-note};
170 1   50     3 $tuv{$lang} = $tuv{$lang}{-seg} || "";
171             }
172 2         3 $self->_startTag(0, 'seg');
173 2 50       7 if ($verbatim) {
    50          
174 0         0 $self->_write($tuv{$lang});
175             } elsif ($cdata) {
176 0         0 $self->_write("
177 0         0 $self->_write($tuv{$lang});
178 0         0 $self->_write("]]>");
179             } else {
180 2         4 $self->_characters($tuv{$lang});
181             }
182 2         4 $self->_endTag('seg');
183 2         3 $self->_endTag('tuv')->_nl;
184             }
185 1         2 $self->_endTag('tu')->_nl->_nl;
186             }
187              
188              
189              
190             sub end_tmx {
191 1     1 1 5 my $self = shift();
192 1         3 $self->_endTag('body')->_nl;
193 1         1 $self->_endTag('tmx')->_nl;
194 1         41 close($self->{OUTPUT});
195             }
196              
197              
198             sub _write {
199 120     120   125 my $self = shift;
200 120         112 print {$self->{OUTPUT}} @_;
  120         192  
201 120         205 return $self;
202             }
203              
204             sub _nl {
205 28     28   31 my $self = shift;
206 28         36 $self->_write("\n");
207             }
208              
209             sub _startTag {
210 24     24   44 my ($self, $indent, $tagName, %attributes) = @_;
211 24         26 my $attributes = "";
212 24 100       50 $attributes = " ".join(" ",map {"$_=\"$attributes{$_}\""} sort keys %attributes) if %attributes;
  19         50  
213 24         39 $self->_indent($indent)->_write("<$tagName$attributes>");
214             }
215              
216             sub _indent {
217 25     25   30 my ($self, $indent) = @_;
218 25         34 $indent = " " x $indent;
219 25         33 $self->_write($indent);
220             }
221              
222             sub _characters {
223 18     18   26 my ($self, $text) = @_;
224              
225 18 50       26 $text = "" unless defined $text;
226 18         25 $text =~ s/\n/ /g;
227 18         19 $text =~ s/ +/ /g;
228 18         19 $text =~ s/&/&/g;
229 18         19 $text =~ s/
230 18         21 $text =~ s/>/>/g;
231 18         13 $text =~ s!<(b|emph)>(.+?)</\1>!<$1>$2!gs;
232              
233 18         27 $self->_write($text);
234             }
235              
236             sub _endTag {
237 24     24   33 my ($self, $tagName) = @_;
238              
239 24         36 $self->_write("");
240             }
241              
242             1;
243              
244             __END__