File Coverage

blib/lib/MealMaster.pm
Criterion Covered Total %
statement 113 113 100.0
branch 33 40 82.5
condition 14 15 93.3
subroutine 7 7 100.0
pod 1 1 100.0
total 168 176 95.4


line stmt bran cond sub pod time code
1             package MealMaster;
2 1     1   818 use strict;
  1         3  
  1         36  
3 1     1   508 use MealMaster::Recipe;
  1         2  
  1         8  
4 1     1   625 use MealMaster::Ingredient;
  1         2  
  1         8  
5             our $VERSION = "0.28";
6 1     1   37 use base qw(Class::Accessor::Chained::Fast);
  1         2  
  1         1557  
7              
8             sub parse {
9 2     2 1 29184 my ($self, $filename) = @_;
10              
11 2 50       127 open(my $fh, $filename) || die $!;
12 2         8036 my $file = join '', <$fh>;
13              
14 2 50       459 return unless $file =~ /^(MMMMM|-----).+Meal-Master/;
15              
16 2         4437 my @parts = split /^(?:MMMMM|-----).+Meal-Master.+$/m, $file;
17 2         12 my @recipes;
18              
19 2         10 foreach my $part (@parts) {
20 244         1547 $part =~ s/^\s+//;
21 244         718 my $recipe = MealMaster::Recipe->new;
22 244         5353 my $lines = [ split /\n/, $part ];
23              
24 244         605 my $line;
25              
26 244         249 while (1) {
27 244         457 $line = $self->_newline($lines);
28 244 100       467 last unless defined $line;
29 242 50       657 last if $line =~ /Title:/;
30             }
31 244 100       398 next unless defined $line;
32              
33 242         957 my ($title) = $line =~ /Title: (.+)$/;
34 242 50       656 next unless $title;
35 242         284 $title =~ s/^ +//;
36 242         522 $title =~ s/ +$//;
37 242         642 $recipe->title($title);
38              
39 242         1935 $line = $self->_newline($lines);
40 242         886 my ($categories) = $line =~ /Categories: (.+)$/;
41              
42 242         259 my @categories;
43 242 50       809 @categories = split ', ', $categories if $categories;
44 242         710 $recipe->categories(\@categories);
45              
46 242         1583 $line = $self->_newline($lines);
47 242         1097 my ($yield) = $line =~ /(?:Yield|Servings): +(.+)$/;
48 242 50       465 next unless $yield;
49 242         685 $recipe->yield($yield);
50              
51 242         1476 my $dflag = 0;
52 242         248 my $ingredients;
53             my $directions;
54              
55 242         421 while (defined($line = $self->_newline($lines))) {
56 5442 100       9689 next unless $line;
57              
58 5420 50       8019 last if (!defined $line);
59 5420 100 100     17270 next if (($dflag == 0) && ($line =~ m|^\s*$|));
60              
61 4935 100 100     37933 if ($line =~ /^[M-]+$/) {
    100 100        
    100          
    100          
62 242         288 last;
63             } elsif ($line =~ m(^[M|-]{4,})) {
64 32         88 $line =~ s|^MMMMM||;
65 32         99 $line =~ s|^\-+||;
66 32         93 $line =~ s|\-+$||;
67 32         45 $line =~ s|^ +||;
68 32         37 $line =~ s|:$||;
69 32         83 $directions .= "$line\n";
70             } elsif ($line =~ m/^ *([A-Z ]+):$/) {
71 10         29 $directions .= "$line\n";
72             } elsif (length($line) > 12
73             && (substr($line, 0, 7) =~ m|^[ 0-9\.\/]+$|)
74             && (substr($line, 7, 4) =~ m|^ .. $|))
75             {
76 1755         4927 $ingredients .= "$line\n";
77             } else {
78 2896         7411 $line =~ s|^\s+||;
79 2896 100       6859 if ($line) {
80 2281         2980 $directions .= "$line\n";
81 2281         5017 $dflag = 1;
82             }
83             }
84             }
85              
86 242         445 $ingredients = $self->_parse_ingredients($ingredients);
87              
88 242         607 $recipe->ingredients($ingredients);
89 242         1938 $recipe->directions($directions);
90              
91 242         2121 push @recipes, $recipe;
92             }
93 2         1227 return @recipes;
94             }
95              
96             sub _parse_ingredients {
97 242     242   328 my ($self, $text) = @_;
98              
99 242 100       417 return [] unless $text;
100              
101 240         221 my @ingredients;
102             my @ingredients2;
103 240         987 foreach my $line (split "\n", $text) {
104              
105             # Two-column case:
106             # 1/3 c Instant cream of wheat
107              
108             # 1 1/3 c Brown Sugar, Firmly Packed 1 c Unbleached Flour
109             # 12345678910121416182022242628303234363840424446485052
110 1755 100 100     6065 if (length($line) > 40 && $line =~ /^.{40} ...... .. ./) {
111 491         803 my $quantity = substr($line, 0, 7);
112 491         646 my $measure = substr($line, 8, 2);
113 491         762 my $product = substr($line, 11, 29);
114 491         1332 $quantity =~ s/^ +//;
115 491         1538 $measure =~ s/ ? ?$//;
116 491         1484 $product =~ s/ +$//;
117 491         1477 my $i =
118             MealMaster::Ingredient->new->quantity($quantity)->measure($measure)
119             ->product($product);
120 491         11227 push @ingredients, $i;
121 491         754 $quantity = substr($line, 41, 7);
122 491         550 $measure = substr($line, 49, 2);
123 491         765 $product = substr($line, 52);
124 491         1385 $quantity =~ s/^ +//;
125 491         1502 $measure =~ s/ ? ?$//;
126 491         1411 $i =
127             MealMaster::Ingredient->new->quantity($quantity)->measure($measure)
128             ->product($product);
129 491         11545 push @ingredients2, $i;
130             } else {
131              
132             # Simple case:
133             # 1/4 c Butter or margarine
134 1264         1560 my $quantity = substr($line, 0, 7);
135 1264         1370 my $measure = substr($line, 8, 2);
136 1264         1483 my $product = substr($line, 11);
137 1264         3160 $quantity =~ s/^ +//;
138 1264         3286 $measure =~ s/ ? ?$//;
139 1264         2191 $product =~ s/ +$//;
140 1264         3164 my $i =
141             MealMaster::Ingredient->new->quantity($quantity)->measure($measure)
142             ->product($product);
143 1264         26381 push @ingredients, $i;
144             }
145             }
146              
147 240         1072 @ingredients = (@ingredients, @ingredients2);
148              
149             # Fold
150             # 1/3 c Instant cream of wheat
151             # -(prepared)
152             # to:
153             # 1/3 c Instant cream of wheat (prepared)
154              
155 240         441 my @folded_ingredients = ($ingredients[0]);
156 240         513 foreach my $n (1 .. @ingredients - 1) {
157 2006         2637 my $i = $ingredients[$n];
158 2006 100 66     6789 if ( not defined $i->quantity
159             && not defined $i->measure
160             && $i->product =~ /^-/)
161             {
162 99         1787 my $extra = $i->product;
163 99         587 $extra =~ s/^--?//;
164 99         237 my $old = $folded_ingredients[-1]->product;
165 99         490 my $new = "$old $extra";
166 99         211 $folded_ingredients[-1]->product($new);
167             } else {
168 1907         36121 push @folded_ingredients, $i;
169             }
170             }
171              
172 240         977 return \@folded_ingredients;
173             }
174              
175             sub _newline {
176 6170     6170   7500 my ($self, $lines) = @_;
177 6170         7451 my $line = shift @$lines;
178 6170 100       11029 return unless defined $line;
179 6168         21169 $line =~ s{\r|\n|\t}{}g;
180 6168         7598 chomp $line;
181 6168         14574 return $line;
182             }
183              
184             1;
185              
186             __END__