File Coverage

blib/lib/Data/Phrasebook/Loader/Text.pm
Criterion Covered Total %
statement 73 73 100.0
branch 26 32 81.2
condition 22 33 66.6
subroutine 10 10 100.0
pod 4 4 100.0
total 135 152 88.8


line stmt bran cond sub pod time code
1             package Data::Phrasebook::Loader::Text;
2 12     12   17161 use strict;
  12         29  
  12         542  
3 12     12   107 use warnings FATAL => 'all';
  12         65  
  12         576  
4 12     12   66 use base qw( Data::Phrasebook::Loader::Base Data::Phrasebook::Debug );
  12         22  
  12         5579  
5 12     12   65 use Carp qw( croak );
  12         33  
  12         581  
6 12     12   22271 use IO::File;
  12         169798  
  12         2685  
7              
8 12     12   137 use vars qw($VERSION);
  12         26  
  12         15445  
9             $VERSION = '0.35';
10              
11             =head1 NAME
12              
13             Data::Phrasebook::Loader::Text - Absract your phrases with plain text files.
14              
15             =head1 SYNOPSIS
16              
17             use Data::Phrasebook;
18              
19             my $q = Data::Phrasebook->new(
20             class => 'Fnerk',
21             loader => 'Text',
22             file => 'phrases.txt',
23             );
24              
25             # use default delimiters (:variable)
26             my $phrase = $q->fetch($keyword,{variable => 'substitute'});
27              
28             # use Template Toolkit style delimiters
29             $q->delimiters( qr{ \[% \s* (\w+) \s* %\] }x );
30             my $phrase = $q->fetch($keyword,{variable => 'substitute'});
31              
32             =head1 DESCRIPTION
33              
34             This loader plugin implements phrasebook patterns using plain text files.
35              
36             Phrases can be contained within one or more dictionaries, with each phrase
37             accessible via a unique key. Phrases may contain placeholders, please see
38             L for an explanation of how to use these. Groups of phrases
39             are kept in a dictionary. In this implementation a single file is one
40             complete dictionary.
41              
42             An example plain text file:
43              
44             foo=Welcome to :my world. It is a nice :place.
45              
46             Within the phrase text placeholders can be used, which are then replaced with
47             the appropriate values once the get() method is called. The default style of
48             placeholders can be altered using the delimiters() method.
49              
50             =head1 INHERITANCE
51              
52             L inherits from the base class
53             L.
54             See that module for other available methods and documentation.
55              
56             =head1 METHODS
57              
58             =head2 load
59              
60             Given a C, load it. C must contain a valid phrase map.
61              
62             my $file = 'english.txt';
63             $loader->load( $file );
64              
65             This method is used internally by L's
66             C method, to initialise the data store.
67              
68             To utilise the dictionary framework for a Plain Text phrasebook, the idea is
69             to use a directory of files, where the directory is passed via the C
70             argument and the dictionary, the specific name of the file, is passed via
71             the C argument.
72              
73             my $file = '/tmp/phrasebooks';
74             my $dictionary = 'english.txt';
75             $loader->load( $file, $dictionary );
76              
77             =cut
78              
79             my %phrasebook;
80              
81             sub load {
82 17     17 1 43 my ($class, $file, @dict) = @_;
83 17 100       61 $class->store(3,"->load IN - @_") if($class->debug);
84 17   33     64 $file ||= $class->{parent}->file;
85 17 100       91 @dict = $class->{parent}->dict unless(@dict);
86 17 50       56 croak "No file given as argument!" unless defined $file;
87              
88 17         29 my @file;
89 17 100       55 if(@dict) {
90 4         17 while(@dict) {
91 6         11 my $dict = pop @dict; # build phrases in reverse order
92 6         16 $dict = "$file/$dict";
93 6 100 66     459 croak "File [$dict] not accessible!" unless -f $dict && -r $dict;
94 5         16 push @file, $dict;
95             }
96             } else {
97 13 50 33     647 croak "File [$file] not accessible!" unless -f $file && -r $file;
98 13         35 push @file, $file;
99             }
100              
101 16         50 %phrasebook = (); # ignore previous dictionary
102              
103 16         37 for my $file (@file) {
104 18 50       165 my $book = IO::File->new($file) or next;
105 18         6384 while(<$book>) {
106 42         225 my ($name,$value) = (/(.*?)=(.*)/);
107 42 100       294 $phrasebook{$name} = $value if($name); # value can be blank
108             }
109 18         103 $book->close;
110             }
111              
112 16         353 return;
113             }
114              
115             =head2 get
116              
117             Returns the phrase stored in the phrasebook, for a given keyword.
118              
119             my $value = $loader->get( $key );
120              
121             =cut
122              
123             sub get {
124 22     22 1 41 my ($class, $key) = @_;
125 22 100       70 if($class->debug) {
126 2         6 $class->store(3,"->get IN");
127 2         8 $class->store(4,"->get key=[$key]");
128 2         8 $class->store(4,"->get phrase=[$phrasebook{$key}]");
129             }
130 22         142 return $phrasebook{$key};
131             }
132              
133             =head2 dicts
134              
135             Having instantiated the C object class, and using the C
136             attribute as a directory path, the object can return a list of the current
137             dictionaries available as:
138              
139             my $pb = Data::Phrasebook->new(
140             loader => 'Text',
141             file => '/tmp/phrasebooks',
142             );
143              
144             my @dicts = $pb->dicts;
145              
146             or
147              
148             my @dicts = $pb->dicts( $path );
149              
150             =cut
151              
152             sub dicts {
153 3     3 1 7 my ($self,$path) = @_;
154 3   100     25 $path ||= $self->{parent}->file;
155 3 100 100     107 return () unless($path && -d $path && -r $path);
      66        
156              
157 1         176 my @files = map { my $x = $_ ; $x =~ s/$path.//; $x } grep {/^[^\.]+.txt$/} glob("$path/*");
  3         5  
  3         22  
  3         9  
  3         14  
158 1         20 return @files;
159             }
160              
161             =head2 keywords
162              
163             Having instantiated the C object class, using the C
164             and C attributes as required, the object can return a list of the
165             current keywords available as:
166              
167             my $pb = Data::Phrasebook->new(
168             loader => 'Text',
169             file => '/tmp/phrasebooks',
170             dict => 'TEST',
171             );
172              
173             my @keywords = $pb->keywords;
174              
175             or
176              
177             my @keywords = $pb->keywords( $path, $dict );
178              
179             Note that $path can either be the directory path, where $dict must be the
180             specific file name of the dictionary, or the full path of the dictionary file.
181              
182             In the second instance, the function will not load a dictionary, but can be
183             used to interrogate the contents of a known dictionary.
184              
185             =cut
186              
187             sub keywords {
188 7     7 1 11 my @keywords;
189              
190 7 100       28 if(@_ == 1) {
191 1         5 @keywords = sort keys %phrasebook;
192 1         4 return @keywords;
193             }
194              
195 6         15 my ($self,$file,$dict) = @_;
196 6   66     26 $file ||= $self->{parent}->file;
197 6   66     36 $dict ||= $self->{parent}->dict;
198 6 50       16 croak "No file given as argument!" unless defined $file;
199              
200 6 100 100     156 $file = "$file/$dict" if(-d $file && defined $dict);
201 6 100 66     2443 croak "File [$file] not accessible!" unless -f $file && -r $file;
202              
203 1 50       6 my $book = IO::File->new($file) or return;
204 1         76 while(<$book>) {
205 2 50 33     20 push @keywords, $1 if(/(.*?)=/ && $1);
206             }
207 1         4 $book->close;
208              
209 1         12 my %keywords = map { $_ => 1 } @keywords;
  2         7  
210 1         7 @keywords = sort keys %keywords;
211 1         8 return @keywords;
212             }
213              
214             1;
215              
216             __END__