File Coverage

blib/lib/Dist/Zilla/Plugin/MapMetro/MakeLinePod.pm
Criterion Covered Total %
statement 35 117 29.9
branch 0 24 0.0
condition n/a
subroutine 12 20 60.0
pod 0 3 0.0
total 47 164 28.6


line stmt bran cond sub pod time code
1 1     1   20411 use 5.10.1;
  1         4  
2 1     1   5 use strict;
  1         2  
  1         21  
3 1     1   5 use warnings;
  1         2  
  1         25  
4 1     1   874 use utf8;
  1         10  
  1         5  
5              
6             package Dist::Zilla::Plugin::MapMetro::MakeLinePod;
7              
8             our $VERSION = '0.1202'; # VERSION
9             # ABSTRACT: Automatically include line and station info in Map::Metro map
10              
11 1     1   945 use Moose;
  1         528948  
  1         7  
12 1     1   7831 use namespace::autoclean;
  1         8507  
  1         4  
13 1     1   1213 use Path::Tiny;
  1         10032  
  1         68  
14 1     1   959 use List::AllUtils qw/any all uniq/;
  1         4238  
  1         108  
15 1     1   915 use Types::Standard qw/Str Maybe/;
  1         66093  
  1         15  
16 1     1   1702 use Map::Metro::Shim;
  1         3838633  
  1         51  
17 1     1   942 use syntax 'qi';
  1         1504  
  1         5  
18              
19 1     1   12585 use Dist::Zilla::File::InMemory;
  1         157007  
  1         2230  
20             with 'Dist::Zilla::Role::FileGatherer';
21              
22             has cityname => (
23             is => 'rw',
24             isa => Maybe[Str],
25             predicate => 1,
26             );
27              
28             sub gather_files {
29 0     0 0   my $self = shift;
30 0           my $arg = shift;
31              
32 0 0         return if $ENV{'MMNOLINES'};
33 0           $self->log('Set MMNOLINES=1 to skip building Lines.pod');
34              
35 0           my @cities = path(qw/lib Map Metro Plugin Map/)->children(qr/\.pm/);
36 0 0         return if !scalar @cities;
37              
38 0           my @mapfiles = path('share')->children(qr{map-.*\.metro});
39 0 0         return if !scalar @mapfiles;
40              
41 0           my $city = (shift @cities)->basename;
42 0           $city =~ s{\.pm}{};
43 0           my $mapfile = shift @mapfiles;
44              
45 0           my $graph = Map::Metro::Shim->new(filepath => $mapfile)->parse(override_line_change_weight => 99999999);
46              
47 0           my @linepod = ();
48              
49             LINE:
50 0           foreach my $line ($graph->all_lines) {
51              
52 0           my $css_line_id = $line->description;
53 0           $css_line_id =~ s{ }{-}g;
54 0           $css_line_id =~ s{[^a-z0-9_-]}{}ig;
55              
56             my @stations = $graph->filter_stations(sub {
57 0     0     my $station = $_;
58 0           return any { $_->id eq $line->id } $station->all_lines;
  0            
59 0           });
60 0           $self->log(sprintf 'Line %s, found %s stations', $line->name, scalar @stations);
61              
62 0           my @routes;
63             ORIGIN:
64 0           foreach my $i (0 .. $#stations) {
65 0           my $origin_station = $stations[ $i ];
66              
67              
68             DESTINATION:
69 0           foreach my $j (0 .. $#stations) {
70 0           my $destination_station = $stations[ $j ];
71 0 0         next DESTINATION if $origin_station->id == $destination_station->id;
72              
73 0           my $route = $graph->routing_for($origin_station->id, $destination_station->id)->get_route(0);
74 0 0         push @routes => $route if defined $route;
75             }
76             }
77              
78             # Find the two longest routes (termini<->termini, and then pick the alphabetical order)
79 0           my $chosen_route = (sort { $a->get_step(0)->origin_line_station->station->name cmp $b->get_step(0)->origin_line_station->station->name }
80 0           (sort { $b->step_count <=> $a->step_count } @routes)[0, 1]
  0            
81             )[0];
82              
83 0           my $longest_station_name_length = length ((sort { length $b->name <=> length $a->name } @stations)[0]->name);
  0            
84              
85 0           my @station_pod;
86 0           foreach my $step ($chosen_route->all_steps) {
87 0           my @change_to_strings = $self->make_change_to_string($graph, $step->origin_line_station);
88 0 0         if(scalar @change_to_strings) {
89 0           unshift @change_to_strings => ' ' x ($longest_station_name_length - length $step->origin_line_station->station->name);
90             }
91 0           push @station_pod => (' ' x 5) . join ' ' => $step->origin_line_station->station->name, @change_to_strings;
92              
93 0 0         if(!$step->has_next_step) {
94 0           @change_to_strings = $self->make_change_to_string($graph, $step->destination_line_station);
95 0 0         if(scalar @change_to_strings) {
96 0           unshift @change_to_strings => ' ' x ($longest_station_name_length - length $step->destination_line_station->station->name);
97             }
98              
99 0           push @station_pod => (' ' x 5) . join ' ' => $step->destination_line_station->station->name, @change_to_strings;
100             }
101             }
102              
103 0           push @linepod => sprintf '=head2 %s: %s → %s [%s]' => $line->description,
104             $chosen_route->get_step(0)->origin_line_station->station->name,
105             $chosen_route->get_step(-1)->destination_line_station->station->name,
106             $line->name;
107 0           my $css_color = $line->color;
108 0           push @linepod => qq{
109             =for HTML <div style="background-color: $css_color; margin-top: -23px; margin-left: 10px; height: 3px; width: 98%%;"></div>
110             };
111              
112 0           push @linepod => '', @station_pod, '';
113              
114             }
115              
116 0           my $file = Dist::Zilla::File::InMemory->new(
117             name => "lib/Map/Metro/Plugin/Map/$city/Lines.pod",
118             content => $self->make_line_contents($city, @linepod),
119             );
120 0           $self->add_file($file);
121              
122 0           return;
123             }
124              
125             sub make_change_to_string {
126 0     0 0   my $self = shift;
127 0           my $graph = shift;
128 0           my $line_station = shift;
129              
130 0           my @change_strings = ();
131 0     0     my @other_lines = map { $_->name } $line_station->station->filter_lines(sub { $_->id ne $line_station->line->id });
  0            
  0            
132 0     0     @other_lines = (all { $_ =~ /^\d+$/ } @other_lines) ? sort { $a <=> $b } @other_lines
  0            
133 0 0         : sort { $a cmp $b } @other_lines
  0            
134             ;
135              
136 0 0         push @change_strings => scalar @other_lines ? sprintf '(%s)', join ', ' => @other_lines
137             : ()
138             ;
139              
140 0     0     my @transfers = $graph->filter_transfers(sub { $_->origin_station->id == $line_station->station->id });
  0            
141             push @change_strings => scalar @transfers ? join ' ' => map {
142 0 0         sprintf ('[%s: %s]', $_->destination_station->name,
143 0           join ', ' => map { $_->name } $_->destination_station->all_lines )
  0            
144             } @transfers
145             : ()
146             ;
147              
148 0     0     @transfers = $graph->filter_transfers(sub { $_->destination_station->id == $line_station->station->id });
  0            
149             push @change_strings => scalar @transfers ? join ' ' => map {
150 0 0         sprintf ('[%s: %s]', $_->origin_station->name,
151 0           join ', ' => map { $_->name } $_->origin_station->all_lines )
  0            
152             } @transfers
153             : ()
154             ;
155              
156 0           return @change_strings;
157             }
158              
159             sub make_line_contents {
160 0     0 0   my $self = shift;
161 0           my $city = shift;
162 0           my $content = join "\n" => @_;
163              
164 0           $content = sprintf qqi{
165             # %s: Map::Metro::Plugin::Map::${city}::Lines
166             # %s: Lines and stations in the $city map
167              
168             =pod
169              
170             =encoding utf-8
171              
172             =head1 LINES
173              
174             $content
175              
176             =head1 SEE ALSO
177              
178             =for :list
179             * L<Map::Metro::Plugin::Map::$city>
180             * L<Task::MapMetro::Maps>
181             * L<Map::Metro>
182              
183             =cut
184             }, 'PODNAME', 'ABSTRACT';
185              
186 0           $content =~ s{\s+=(begin|end|for)}{\n\n=$1}g;
187              
188 0           return $content;
189              
190             }
191              
192             __PACKAGE__->meta->make_immutable;
193              
194             1;
195              
196             __END__
197              
198             =pod
199              
200             =encoding utf-8
201              
202             =head1 NAME
203              
204             Dist::Zilla::Plugin::MapMetro::MakeLinePod - Automatically include line and station info in Map::Metro map
205              
206              
207              
208             =begin HTML
209              
210             <p><img src="https://img.shields.io/badge/perl-5.14+-brightgreen.svg" alt="Requires Perl 5.14+" /> <a href="https://travis-ci.org/Csson/p5-Dist-Zilla-Plugin-MapMetro-MakeLinePod"><img src="https://api.travis-ci.org/Csson/p5-Dist-Zilla-Plugin-MapMetro-MakeLinePod.svg?branch=master" alt="Travis status" /></a></p>
211              
212             =end HTML
213              
214              
215             =begin markdown
216              
217             ![Requires Perl 5.14+](https://img.shields.io/badge/perl-5.14+-brightgreen.svg) [![Travis status](https://api.travis-ci.org/Csson/p5-Dist-Zilla-Plugin-MapMetro-MakeLinePod.svg?branch=master)](https://travis-ci.org/Csson/p5-Dist-Zilla-Plugin-MapMetro-MakeLinePod)
218              
219             =end markdown
220              
221             =head1 VERSION
222              
223             Version 0.1202, released 2015-11-02.
224              
225             =head1 SYNOPSIS
226              
227             ; in dist.ini
228             [MapMetro::MakeLinePod]
229              
230             =head1 DESCRIPTION
231              
232             This L<Dist::Zilla> plugin creates a C<::Lines> pod detailing all lines, stations, changes and transfers in the map.
233              
234             =head1 SEE ALSO
235              
236             =over 4
237              
238             =item *
239              
240             L<Task::MapMetro::Dev> - Map::Metro development tools
241              
242             =item *
243              
244             L<Map::Metro::Plugin::Map::Barcelona::Lines> - An example
245              
246             =item *
247              
248             L<Map::Metro>
249              
250             =item *
251              
252             L<Map::Metro::Plugin::Map>
253              
254             =back
255              
256             =head1 SOURCE
257              
258             L<https://github.com/Csson/p5-Dist-Zilla-Plugin-MapMetro-MakeLinePod>
259              
260             =head1 HOMEPAGE
261              
262             L<https://metacpan.org/release/Dist-Zilla-Plugin-MapMetro-MakeLinePod>
263              
264             =head1 AUTHOR
265              
266             Erik Carlsson <info@code301.com>
267              
268             =head1 COPYRIGHT AND LICENSE
269              
270             This software is copyright (c) 2015 by Erik Carlsson.
271              
272             This is free software; you can redistribute it and/or modify it under
273             the same terms as the Perl 5 programming language system itself.
274              
275             =cut