File Coverage

blib/lib/Map/Tube/Text/Table.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Map::Tube::Text::Table;
2              
3             # Pragmas.
4 3     3   46862 use strict;
  3         7  
  3         135  
5 3     3   16 use warnings;
  3         5  
  3         129  
6              
7             # Modules.
8 3     3   2122 use Class::Utils qw(set_params);
  0            
  0            
9             use Error::Pure qw(err);
10             use Map::Tube::Text::Table::Utils qw(table);
11             use List::MoreUtils qw(any);
12             use Readonly;
13             use Scalar::Util qw(blessed);
14              
15             # Constants.
16             Readonly::Scalar our $CONNECTED_TO => q{Connected to};
17             Readonly::Scalar our $ID => q{ID};
18             Readonly::Scalar our $JUNCTIONS => q{Junctions};
19             Readonly::Scalar our $LINE => q{Line};
20             Readonly::Scalar our $LINES => q{Lines};
21             Readonly::Scalar our $STATION => q{Station};
22              
23             # Version.
24             our $VERSION = 0.04;
25              
26             # Constructor.
27             sub new {
28             my ($class, @params) = @_;
29              
30             # Create object.
31             my $self = bless {}, $class;
32              
33             # Print ids.
34             $self->{'print_id'} = 0;
35              
36             # Map::Tube object.
37             $self->{'tube'} = undef;
38              
39             # Process params.
40             set_params($self, @params);
41              
42             # Check Map::Tube object.
43             if (! defined $self->{'tube'}) {
44             err "Parameter 'tube' is required.";
45             }
46             if (! blessed($self->{'tube'})
47             || ! $self->{'tube'}->does('Map::Tube')) {
48              
49             err "Parameter 'tube' must be 'Map::Tube' object.";
50             }
51              
52             # Object.
53             return $self;
54             }
55              
56             # Print junctions.
57             sub junctions {
58             my $self = shift;
59              
60             # Get data.
61             my @data;
62             my @title = ($STATION, $LINE, $CONNECTED_TO);
63             my @data_len = map { length $_ } @title;
64             my $nodes_hr = $self->{'tube'}->nodes;
65             foreach my $node_name (sort keys %{$nodes_hr}) {
66             if (@{$nodes_hr->{$node_name}->line} > 1) {
67              
68             # Get data.
69             my @links = map { $self->{'tube'}->get_node_by_id($_)->name }
70             split m/,/ms, $nodes_hr->{$node_name}->link;
71             my $data_ar = [
72             $nodes_hr->{$node_name}->name,
73             (join ', ', map { $_->name } @{$nodes_hr->{$node_name}->line}),
74             (join ', ', sort @links),
75             ];
76             push @data, $data_ar;
77              
78             # Maximum data length.
79             foreach my $i (0 .. $#{$data_ar}) {
80             if (length $data_ar->[$i] > $data_len[$i]) {
81             $data_len[$i] = length $data_ar->[$i];
82             }
83             }
84             }
85             }
86              
87             # Print and return table.
88             return table($JUNCTIONS, \@data_len, \@title, \@data);
89             }
90              
91             # Print line.
92             sub line {
93             my ($self, $line) = @_;
94              
95             # Get data.
96             my @data;
97             my @title = ($STATION, $CONNECTED_TO);
98             if ($self->{'print_id'}) {
99             unshift @title, $ID;
100             }
101             my @data_len = map { length $_ } @title;
102             my $nodes_hr = $self->{'tube'}->nodes;
103             foreach my $node_name (sort keys %{$nodes_hr}) {
104             if (any { $_ eq $line } map { $_->name }
105             @{$nodes_hr->{$node_name}->line}) {
106              
107             # Get data.
108             my @links = map { $self->{'tube'}->get_node_by_id($_)->name }
109             split m/,/ms, $nodes_hr->{$node_name}->link;
110             my $data_ar = [
111             $nodes_hr->{$node_name}->name,
112             (join ', ', sort @links),
113             ];
114             if ($self->{'print_id'}) {
115             unshift @{$data_ar}, $nodes_hr->{$node_name}->id,
116             }
117             push @data, $data_ar;
118              
119             # Maximum data length.
120             foreach my $i (0 .. $#{$data_ar}) {
121             if (length $data_ar->[$i] > $data_len[$i]) {
122             $data_len[$i] = length $data_ar->[$i];
123             }
124             }
125             }
126             }
127              
128             # Print and return table.
129             return table($LINE." '$line'", \@data_len, \@title, \@data);
130             }
131              
132             # Get lines.
133             sub lines {
134             my $self = shift;
135             my $lines_ar = $self->{'tube'}->get_lines;
136             my $length = 0;
137             my @data;
138             foreach my $line (sort @{$lines_ar}) {
139             push @data, [$line];
140             if (length $line > $length) {
141             $length = length $line;
142             }
143             }
144             return table($LINES, [$length], undef, \@data);
145             }
146              
147             # Print all.
148             sub print {
149             my $self = shift;
150             my $ret = $self->junctions;
151             foreach my $line (@{$self->{'tube'}->get_lines}) {
152             $ret .= $self->line($line->name);
153             }
154             return $ret;
155             }
156              
157             1;
158              
159             __END__
160              
161             =encoding utf8
162              
163             =head1 NAME
164              
165             Map::Tube::Text::Table - Table output for Map::Tube.
166              
167             =head1 SYNOPSIS
168              
169             use Map::Tube::Text::Table;
170             my $obj = Map::Tube::Text::Table->new(%params);
171             my $text = $obj->junctions;
172             my $text = $obj->line($line);
173             my $text = $obj->lines;
174             my $text = $obj->print;
175              
176             =head1 METHODS
177              
178             =over 8
179              
180             =item C<new(%params)>
181              
182             Constructor.
183              
184             =over 8
185              
186             =item * C<print_id>
187              
188             Flag, that means printing of ID.
189             Affected methods:
190             - line()
191             - print() (by line()).
192             Default value is 0.
193              
194             =item * C<tube>
195              
196             Map::Tube object.
197             It is required.
198             Default value is undef.
199              
200             =back
201              
202             =item C<junctions()>
203              
204             Print junctions.
205             Returns string with unicode text table.
206              
207             =item C<line($line)>
208              
209             Print line.
210             Returns string with unicode text table.
211              
212             =item C<lines()>
213              
214             Print sorted lines.
215             Returns string with unicode text table.
216              
217             =item C<print()>
218              
219             Print all (junctions + all lines).
220             Returns string with unicode text table.
221              
222             =back
223              
224             =head1 ERRORS
225              
226             new():
227             Parameter 'tube' is required.
228             Parameter 'tube' must be 'Map::Tube' object.
229             From Class::Utils::set_params():
230             Unknown parameter '%s'.
231              
232             =head1 EXAMPLE
233              
234             # Pragmas.
235             use strict;
236             use warnings;
237              
238             # Modules.
239             use Encode qw(encode_utf8);
240             use English;
241             use Error::Pure qw(err);
242             use Map::Tube::Text::Table;
243              
244             # Error::Pure environment.
245             $ENV{'ERROR_PURE'} = 'AllError';
246              
247             # Arguments.
248             if (@ARGV < 1) {
249             print STDERR "Usage: $0 metro\n";
250             exit 1;
251             }
252             my $metro = $ARGV[0];
253            
254             # Object.
255             my $class = 'Map::Tube::'.$metro;
256             eval "require $class;";
257             if ($EVAL_ERROR) {
258             err "Cannot load '$class' class.",
259             'Error', $EVAL_ERROR;
260             }
261            
262             # Metro object.
263             my $tube = eval "$class->new";
264             if ($EVAL_ERROR) {
265             err "Cannot create object for '$class' class.",
266             'Error', $EVAL_ERROR;
267             }
268            
269             # GraphViz object.
270             my $table = Map::Tube::Text::Table->new(
271             'tube' => $tube,
272             );
273            
274             # Print out.
275             print encode_utf8($table->print);
276              
277             # Output without arguments like:
278             # Usage: /tmp/SZXfa2g154 metro
279              
280             # Output with 'Tbilisi' argument like:
281             # ┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
282             # │ Junctions │
283             # ├──────────────────┬──────────────────────────────────────────┬────────────────────────────────────┤
284             # │ Station │ Line │ Connected to │
285             # ├──────────────────┼──────────────────────────────────────────┼────────────────────────────────────┤
286             # │ სადგურის მოედანი │ ახმეტელი-ვარკეთილის ხაზი,საბურთალოს ხაზი │ მარჯანიშვილი, ნაძალადევი, წერეთელი │
287             # └──────────────────┴──────────────────────────────────────────┴────────────────────────────────────┘
288             # ┌───────────────────────────────────────────────────────────┐
289             # │ Line 'ახმეტელი-ვარკეთილის ხაზი' │
290             # ├──────────────────────┬────────────────────────────────────┤
291             # │ Station │ Connected to │
292             # ├──────────────────────┼────────────────────────────────────┤
293             # │ ახმეტელის თეატრი │ სარაჯიშვილი │
294             # │ სარაჯიშვილი │ ახმეტელის თეატრი, გურამიშვილი │
295             # │ გურამიშვილი │ სარაჯიშვილი, ღრმაღელე │
296             # │ ღრმაღელე │ გურამიშვილი, დიდუბე │
297             # │ დიდუბე │ გოცირიძე, ღრმაღელე │
298             # │ გოცირიძე │ დიდუბე, ნაძალადევი │
299             # │ ნაძალადევი │ გოცირიძე, სადგურის მოედანი │
300             # │ მარჯანიშვილი │ რუსთაველი, სადგურის მოედანი │
301             # │ რუსთაველი │ თავისუფლების მოედანი, მარჯანიშვილი │
302             # │ თავისუფლების მოედანი │ ავლაბარი, რუსთაველი │
303             # │ ავლაბარი │ 300 არაგველი, თავისუფლების მოედანი │
304             # │ 300 არაგველი │ ავლაბარი, ისანი │
305             # │ ისანი │ 300 არაგველი, სამგორი │
306             # │ სამგორი │ ვარკეთილი, ისანი │
307             # │ ვარკეთილი │ სამგორი │
308             # │ სადგურის მოედანი │ მარჯანიშვილი, ნაძალადევი, წერეთელი │
309             # └──────────────────────┴────────────────────────────────────┘
310             # ┌────────────────────────────────────────────────────────────────────┐
311             # │ Line 'საბურთალოს ხაზი' │
312             # ├─────────────────────────┬──────────────────────────────────────────┤
313             # │ Station │ Connected to │
314             # ├─────────────────────────┼──────────────────────────────────────────┤
315             # │ წერეთელი │ სადგურის მოედანი, ტექნიკური უნივერსიტეტი │
316             # │ ტექნიკური უნივერსიტეტი │ სამედიცინო უნივერსიტეტი, წერეთელი │
317             # │ სამედიცინო უნივერსიტეტი │ დელისი, ტექნიკური უნივერსიტეტი │
318             # │ დელისი │ ვაჟა-ფშაველა, სამედიცინო უნივერსიტეტი │
319             # │ ვაჟა-ფშაველა │ დელისი │
320             # │ სადგურის მოედანი │ მარჯანიშვილი, ნაძალადევი, წერეთელი │
321             # └─────────────────────────┴──────────────────────────────────────────┘
322              
323             =head1 DEPENDENCIES
324              
325             L<Class::Utils>,
326             L<Error::Pure>,
327             L<Map::Tube::Text::Table::Utils>,
328             L<List::MoreUtils>,
329             L<Readonly>,
330             L<Scalar::Util>.
331              
332             =head1 SEE ALSO
333              
334             L<Map::Tube>,
335             L<Map::Tube::Graph>,
336             L<Map::Tube::GraphViz>,
337             L<Map::Tube::Plugin::Graph>,
338             L<Task::Map::Tube>.
339              
340             =head1 REPOSITORY
341              
342             L<https://github.com/tupinek/Map-Tube-Text-Table>
343              
344             =head1 AUTHOR
345              
346             Michal Å paček L<mailto:skim@cpan.org>
347              
348             L<http://skim.cz>
349              
350             =head1 LICENSE AND COPYRIGHT
351              
352             © 2014-2015 Michal Å paček
353             Artistic License
354             BSD 2-Clause License
355              
356             =head1 VERSION
357              
358             0.04
359              
360             =cut