File Coverage

blib/lib/GnaData/Parse.pm
Criterion Covered Total %
statement 9 226 3.9
branch 0 64 0.0
condition 0 39 0.0
subroutine 3 29 10.3
pod 0 26 0.0
total 12 384 3.1


line stmt bran cond sub pod time code
1 1     1   679 use strict;
  1         2  
  1         37  
2 1     1   827 use IO::Handle;
  1         33743  
  1         81  
3 1     1   947 use English;
  1         12497  
  1         7  
4              
5             =pod
6             GnaData::Parse
7             =cut
8              
9             package GnaData::Parse;
10              
11             sub new {
12 0     0 0   my $proto = shift;
13 0   0       my $class = ref($proto) || $proto;
14 0           my $self = {};
15 0           bless ($self, $class);
16              
17 0           $self->{'input_handle'} = IO::Handle->new();
18 0           $self->{'input_handle'}->fdopen(fileno(STDIN), "r");
19              
20 0           $self->{'output_handle'} = IO::Handle->new();
21 0           $self->{'output_handle'}->fdopen(fileno(STDOUT), "w");
22              
23 0           $self->{'start_entry'} = "";
24 0           $self->{'end_entry'} = "";
25              
26 0           $self->{'extract_data'} = [];
27            
28 0           $self->{'start_parse'} = "";
29 0           $self->{'end_parse'} = "";
30              
31 0           $self->{'remove_tags_list'} =
32             ["strong", "font", "body", "b", "tt", "ul", "li", "i", "em",
33             "hr", "input", "html", "blockquote",
34             "p", "br", "nobr", "td", "tr", "a", "table", "u",
35             "dd", "dt", "img", "div", "center", "!--", "span"];
36 0           return $self;
37             }
38              
39             sub parse {
40 0     0 0   my ($self) = @_;
41 0           my ($in_entry) = 0;
42 0           my ($in_parse) = 0;
43 0           my ($line) = "";
44 0           my ($start_entry) = $self->{'start_entry'};
45 0           my ($end_entry) = $self->{'end_entry'};
46              
47 0           $self->{'current_entry'} = "";
48              
49 0 0         if ($self->{'start_parse'} eq "") {
50 0           $in_parse = 1;
51             }
52              
53 0           while ($line = $self->{'input_handle'}->getline()) {
54 0           $self->extract_data($line,
55             $self->{'extract_list'});
56 0           $self->{'state'} = "";
57 0 0 0       if (!$in_parse &&
    0 0        
    0 0        
    0 0        
    0 0        
      0        
      0        
      0        
58             $line =~ m!$self->{'start_parse'}!i) {
59 0           $self->{'state'} = "start_parse";
60             } elsif ($in_parse &&
61             $line =~ m!$self->{'end_parse'}!i) {
62 0           $self->{'state'} = "end_parse";
63             } elsif ($in_parse &&
64             defined ($line)
65             && $line =~ m!$start_entry!i) {
66 0           $self->{'state'} = "start_entry";
67             } elsif ($in_parse &&
68             $in_entry &&
69             $end_entry ne "" &&
70             $line =~ m!$end_entry!i) {
71 0           $self->{'state'} = "end_entry";
72             } elsif (! m!^\#! && $in_entry) {
73 0           $self->{'state'} = "read";
74             }
75              
76 0 0         if (defined($self->{'parse_extension'})) {
77 0           &{$self->{'parse_extension'}}($self, $line);
  0            
78             }
79            
80 0 0         if ($self->{'state'} eq "start_parse") {
    0          
    0          
    0          
    0          
81 0           $in_parse = 1;
82             } elsif ($self->{'state'} eq "end_parse") {
83 0 0         if ($in_entry) {
84 0           $self->{'current_entry'} .= $line;
85 0           $self->print_entry($self->{'current_entry'});
86             }
87 0           $in_parse = 0;
88 0           $in_entry = 0;
89 0           $self->{'current_entry'} ="";
90             } elsif ($self->{'state'} eq "start_entry") {
91 0 0         if ($in_entry) {
92 0           $self->print_entry($self->{'current_entry'});
93             }
94 0           $in_entry = 1;
95 0           $self->{'current_entry'} = $line;
96             } elsif ($self->{'state'} eq "end_entry") {
97 0           $in_entry = 0;
98 0           $self->{'current_entry'} .= $line;
99 0           $self->print_entry($self->{'current_entry'});
100 0           $self->{'current_entry'}="";
101             } elsif ($self->{'state'} eq "read") {
102 0           $self->{'current_entry'} .= $line;
103             }
104             }
105              
106 0 0 0       if ($in_parse && $in_entry) {
107 0           $self->print_entry($self->{'current_entry'});
108             }
109             }
110              
111             sub parse_entry {
112 0     0 0   my ($self, $entry) = @_;
113 0           $entry =~ s!\r!!gi;
114 0           $entry =~ s!\n!\n !gi;
115 0           $entry =~ s! ! !gi;
116 0 0         if (defined($self->{'preprocess'})) {
117 0           $entry = &{$self->{'preprocess'}}($self, $entry);
  0            
118             }
119 0 0         if ($entry =~ m/^\s*$/) {
120 0           return "";
121             }
122              
123             $entry =
124 0           $self->substitute_fields($entry,
125             $self->{'substitute_list'});
126 0           $entry =
127             &remove_tags($entry, $self->{'remove_tags_list'});
128              
129             # Convert currencies (remember that we are international)
130 0           $entry =~ s!\$!US\$!g;
131              
132             # Add fields to the end
133              
134 0           $entry = $self->transform_entry ($entry,
135             $self->{'extract_data'});
136              
137             # Remove excess blank space
138              
139 0           $entry =~ s!\n\s*\n!\n!gi;
140 0           $entry =~ s!(\S)\s*\n!$1\n!g;
141            
142             # convert high orderr characters to entities
143 0           $entry =~ s!([\x7f-\xff])\s*!"\&\#" . ord($1). "\;"!ge;
  0            
144 0 0         if ($entry =~ m/^\s*$/) {
145 0           return "";
146             }
147              
148 0           $entry = $self->transform_entry($entry, $self->{'transform_list'});
149 0           $entry = "\n" . $entry;
150 0 0         if (defined($self->{'postprocess'})) {
151 0           $entry = &{$self->{'postprocess'}}($self, $entry);
  0            
152             }
153              
154              
155 0           return $entry;
156             }
157              
158             sub dump_list {
159 0     0 0   my ($self, $list) = @_;
160 0           my ($item);
161 0           $self->print("\n# Dumping list\n");
162 0           foreach $item (@{$list}) {
  0            
163 0           my ($field) = $item->[0];
164 0           my ($func) = $item->[1];
165 0           $self->print("\n# $field $func\n");
166             }
167             }
168              
169             sub transform_entry {
170 0     0 0   my ($self, $entry, $transform_list) = @_;
171 0           my (@fields) = ();
172 0           my ($item);
173 0           my (%field_values) = ();
174 0           $self->split_entry($entry, \@fields, \%field_values);
175 0           foreach $item (@{$transform_list}) {
  0            
176 0           my ($field) = $item->[0];
177 0           my ($func) = $item->[1];
178             # Note that here I mean exists and not undefined. I only add the item to
179             # the field list if the hash value has never been defined
180 0 0         if (!exists($field_values{$field})) {
181 0           push (@fields, $field);
182             }
183 0 0         if (ref($func) eq "CODE") {
184 0           $field_values{$field} =
185             &$func(\%field_values);
186             } else {
187              
188 0           $field_values{$field} =
189             $func;
190             }
191             }
192 0           return $self->join_entry(\@fields, \%field_values);
193             }
194              
195             sub split_entry {
196 0     0 0   my ($self, $entry, $listref, $hashref) = @_;
197 0           my ($line);
198 0           my ($current_field) = ".header";
199              
200 0           foreach $line (split(/\n/, $entry)) {
201 0 0 0       if ($line =~ m/^(\S+)\s+(.*)\s*$/) {
    0          
    0          
202 0           $current_field = $1;
203 0           push (@{$listref}, $current_field);
  0            
204 0           $hashref->{$current_field} = $2;
205             } elsif ($line =~ m/^(\S+)\s*$/) {
206 0           $current_field = $1;
207 0           $hashref->{$current_field} = "";
208 0           push (@{$listref}, $current_field);
  0            
209             } elsif ($current_field ne "" &&
210             $line !~ m/^\s*$/) {
211 0           $line =~ s/^\s+/ /gi;
212 0 0         if ($hashref->{$current_field} ne "") {
213 0           $hashref->{$current_field} .= "\n";
214             }
215 0           $hashref->{$current_field} .= $line;
216             }
217             }
218             }
219              
220             sub join_entry {
221 0     0 0   my ($self, $listref, $hashref) = @_;
222 0           my (@list) = ();
223 0           my ($item);
224 0           foreach $item (@{$listref}) {
  0            
225 0 0         if ($item eq ".header") {
226 0           push(@list, "$hashref->{$item}");
227             } else {
228 0 0         if (defined($hashref->{$item})) {
229 0           push(@list, "$item $hashref->{$item}");
230             }
231             }
232             }
233 0           return join("\n", @list);
234             }
235              
236             sub print_entry {
237 0     0 0   my ($self, $entry) = @_;
238 0           $self->print("\n" . $self->parse_entry($entry));
239             }
240              
241             sub print {
242 0     0 0   my ($self, $s) = @_;
243 0           $self->{'output_handle'}->print($s);
244             }
245              
246             sub entry_bounds {
247 0     0 0   my ($self, $start, $end) = @_;
248 0           $self->{'start_entry'} = $start;
249 0           $self->{'end_entry'} = $end;
250             }
251              
252             sub parse_bounds {
253 0     0 0   my ($self, $start, $end) = @_;
254 0           $self->{'start_parse'} = $start;
255 0           $self->{'end_parse'} = $end;
256             }
257              
258             sub extract_data {
259 0     0 0   my ($self, $line, $extract_list) = @_;
260 0           my ($item);
261             loop:
262 0           foreach $item (@$extract_list) {
263 0           my ($field) = $item->[0];
264            
265 0 0 0       if ($field ne ""
266             && $line =~ m!\s*$item->[1]!is) {
267 0           my ($value) = $1;
268 0           my ($item1);
269 0           my ($i) = 0;
270 0           foreach $item1 (@{$self->{'extract_data'}}) {
  0            
271 0 0         if ($item1->[0] eq $field) {
272 0           $self->{'extract_data'}->[$i]->[1] = $value;
273 0           next loop;
274             }
275 0           $i++;
276             }
277 0           push (@{$self->{'extract_data'}},
  0            
278             [$field, $value]);
279             }
280             }
281             }
282              
283              
284             sub extract_list {
285 0     0 0   my ($self, $extract) = @_;
286 0           $self->{'extract_list'} = $extract;
287             }
288              
289             sub parse_extension {
290 0     0 0   my ($self, $parse_extension) = @_;
291 0           $self->{'parse_extension'} = $parse_extension;
292             }
293              
294             sub substitute_list {
295 0     0 0   my ($self, $substitute) = @_;
296 0           $self->{'substitute_list'} = $substitute;
297             }
298              
299             sub transform_list {
300 0     0 0   my ($self, $clean) = @_;
301 0           $self->{'transform_list'} = $clean;
302             }
303              
304             sub remove_tags_list {
305 0     0 0   my ($self, $remove_tags) = @_;
306 0           $self->{'remove_tags_list'} = $remove_tags;
307             }
308              
309             sub preprocess {
310 0     0 0   my ($self, $preprocess) = @_;
311 0           $self->{'preprocess'} = $preprocess;
312             }
313              
314             sub process_line {
315 0     0 0   my ($self, $process_line) = @_;
316 0           $self->{'process_line'} = $process_line;
317             }
318              
319             sub input_handle {
320 0     0 0   my ($self) = shift;
321 0           my ($inh) = shift;
322 0           $self->{'input_handle'} = $inh;
323              
324             }
325              
326             sub output_handle {
327 0     0 0   my ($self, $outh) = @_;
328 0           $self->{'output_handle'} = $outh;
329             }
330              
331              
332             # This is a subroutine to do uncapitalizations
333              
334             sub uncap {
335 0     0 0   my($out) = @_;
336 0           local ($_);
337 0           my($return) = "";
338 0           my(@list) = ();
339 0           $out =~ s/^\s+//g;
340 0           foreach (split(/\s+/, $out)) {
341 0 0         /VLSI/ && next;
342 0 0         /^[IVX]+$/ && next;
343 0           y/A-Z/a-z/;
344 0           /^(.)(.*)$/;
345 0           my($up) = $1;
346 0           my($down) = $2;
347 0           $up =~ tr/a-z/A-Z/;
348 0           push (@list, "$up$down");
349             }
350 0           return join(" ", @list);
351             }
352              
353             sub remove_tags {
354 0     0 0   my($entry, $tag_list) = @_;
355 0           my($tag);
356 0           foreach $tag (@{$tag_list}) {
  0            
357 0           $entry =~ s!]+)*>!!gi;
358             }
359 0           return $entry;
360             }
361              
362             sub append_lines {
363 0     0 0   my($entry, $line_list) = @_;
364 0           my($line);
365 0           foreach $line (@{$line_list}) {
  0            
366            
367 0           $entry =~ s!\s*$!\n$line->[0] $line->[1]\n!i;
368             }
369 0           return $entry;
370             }
371              
372             sub uncap_fields {
373 0     0 0   my ($list_ref) = @_;
374 0           my ($item);
375 0           foreach $item (@$list_ref) {
376 0           s/((^|\n)$item\s+)([^\n]+?(\n\s+[^\n]+?)*(\n|$))/ $1 . &uncap($3) . "\n"/se;
  0            
377             }
378             }
379             sub substitute_fields {
380 0     0 0   my($self, $entry, $list_ref) = @_;
381 0           my($item);
382 0           my ($returnval) = "";
383 0           foreach $item (@$list_ref) {
384 0 0 0       if ($item->[0] ne ""
385             && $entry =~ m!\s*$item->[1]!is) {
386 0           $returnval .= $::PREMATCH . "\n";
387 0           $entry = $::POSTMATCH;
388 0           eval "\$returnval .= \"$item->[0] $item->[2]\"";
389             }
390             }
391              
392 0           $returnval .= $entry;
393 0           return $returnval;
394             }
395              
396             1;
397              
398              
399              
400              
401              
402              
403              
404              
405              
406              
407              
408              
409