File Coverage

blib/lib/Dist/Zilla/Plugin/MapMetro/MakeLinePod.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1 1     1   14474 use 5.10.1;
  1         3  
  1         31  
2 1     1   5 use strict;
  1         1  
  1         27  
3 1     1   3 use warnings;
  1         4  
  1         29  
4 1     1   519 use utf8;
  1         7  
  1         3  
5              
6             package Dist::Zilla::Plugin::MapMetro::MakeLinePod;
7              
8             our $VERSION = '0.1201'; # VERSION
9             # ABSTRACT: Automatically include line and station info in Map::Metro map
10              
11 1     1   951 use Moose;
  0            
  0            
12             use namespace::sweep;
13             use Path::Tiny;
14             use List::AllUtils qw/any all uniq/;
15             use Types::Standard qw/Str Maybe/;
16             use Map::Metro::Shim;
17             use syntax 'qi';
18              
19             use Dist::Zilla::File::InMemory;
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             my $self = shift;
30             my $arg = shift;
31              
32             return if $ENV{'MMNOLINES'};
33             $self->log('Set MMNOLINES=1 to skip building Lines.pod');
34              
35             my @cities = path(qw/lib Map Metro Plugin Map/)->children(qr/\.pm/);
36             return if !scalar @cities;
37              
38             my @mapfiles = path('share')->children(qr{map-.*\.metro});
39             return if !scalar @mapfiles;
40              
41             my $city = (shift @cities)->basename;
42             $city =~ s{\.pm}{};
43             my $mapfile = shift @mapfiles;
44              
45             my $graph = Map::Metro::Shim->new(filepath => $mapfile)->parse(override_line_change_weight => 99999999);
46              
47             my @linepod = ();
48              
49             LINE:
50             foreach my $line ($graph->all_lines) {
51              
52             my $css_line_id = $line->description;
53             $css_line_id =~ s{ }{-}g;
54             $css_line_id =~ s{[^a-z0-9_-]}{}ig;
55              
56             my @stations = $graph->filter_stations(sub {
57             my $station = $_;
58             return any { $_->id eq $line->id } $station->all_lines;
59             });
60             $self->log(sprintf 'Line %s, found %s stations', $line->name, scalar @stations);
61              
62             my @routes;
63             ORIGIN:
64             foreach my $i (0 .. $#stations) {
65             my $origin_station = $stations[ $i ];
66              
67              
68             DESTINATION:
69             foreach my $j (0 .. $#stations) {
70             my $destination_station = $stations[ $j ];
71             next DESTINATION if $origin_station->id == $destination_station->id;
72              
73             my $route = $graph->routing_for($origin_station->id, $destination_station->id)->get_route(0);
74             push @routes => $route if defined $route;
75             }
76             }
77              
78             # Find the two longest routes (termini<->termini, and then pick the alphabetical order)
79             my $chosen_route = (sort { $a->get_step(0)->origin_line_station->station->name cmp $b->get_step(0)->origin_line_station->station->name }
80             (sort { $b->step_count <=> $a->step_count } @routes)[0, 1]
81             )[0];
82              
83             my $longest_station_name_length = length ((sort { length $b->name <=> length $a->name } @stations)[0]->name);
84              
85             my @station_pod;
86             foreach my $step ($chosen_route->all_steps) {
87             my @change_to_strings = $self->make_change_to_string($graph, $step->origin_line_station);
88             if(scalar @change_to_strings) {
89             unshift @change_to_strings => ' ' x ($longest_station_name_length - length $step->origin_line_station->station->name);
90             }
91             push @station_pod => (' ' x 5) . join ' ' => $step->origin_line_station->station->name, @change_to_strings;
92              
93             if(!$step->has_next_step) {
94             @change_to_strings = $self->make_change_to_string($graph, $step->destination_line_station);
95             if(scalar @change_to_strings) {
96             unshift @change_to_strings => ' ' x ($longest_station_name_length - length $step->destination_line_station->station->name);
97             }
98              
99             push @station_pod => (' ' x 5) . join ' ' => $step->destination_line_station->station->name, @change_to_strings;
100             }
101             }
102              
103             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             my $css_color = $line->color;
108             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             push @linepod => '', @station_pod, '';
113              
114             }
115              
116             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             $self->add_file($file);
121              
122             return;
123             }
124              
125             sub make_change_to_string {
126             my $self = shift;
127             my $graph = shift;
128             my $line_station = shift;
129              
130             my @change_strings = ();
131             my @other_lines = map { $_->name } $line_station->station->filter_lines(sub { $_->id ne $line_station->line->id });
132             @other_lines = (all { $_ =~ /^\d+$/ } @other_lines) ? sort { $a <=> $b } @other_lines
133             : sort { $a cmp $b } @other_lines
134             ;
135              
136             push @change_strings => scalar @other_lines ? sprintf '(%s)', join ', ' => @other_lines
137             : ()
138             ;
139              
140             my @transfers = $graph->filter_transfers(sub { $_->origin_station->id == $line_station->station->id });
141             push @change_strings => scalar @transfers ? join ' ' => map {
142             sprintf ('[%s: %s]', $_->destination_station->name,
143             join ', ' => map { $_->name } $_->destination_station->all_lines )
144             } @transfers
145             : ()
146             ;
147              
148             @transfers = $graph->filter_transfers(sub { $_->destination_station->id == $line_station->station->id });
149             push @change_strings => scalar @transfers ? join ' ' => map {
150             sprintf ('[%s: %s]', $_->origin_station->name,
151             join ', ' => map { $_->name } $_->origin_station->all_lines )
152             } @transfers
153             : ()
154             ;
155              
156             return @change_strings;
157             }
158              
159             sub make_line_contents {
160             my $self = shift;
161             my $city = shift;
162             my $content = join "\n" => @_;
163              
164             $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             $content =~ s{\s+=(begin|end|for)}{\n\n=$1}g;
187              
188             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             =head1 VERSION
207              
208             Version 0.1201, released 2015-01-21.
209              
210             =head1 SYNOPSIS
211              
212             ; in dist.ini
213             [MapMetro::MakeLinePod]
214              
215             =head1 DESCRIPTION
216              
217             This L<Dist::Zilla> plugin creates a C<::Lines> pod detailing all lines, stations, changes and transfers in the map.
218              
219             =head1 SEE ALSO
220              
221             =over 4
222              
223             =item *
224              
225             L<Task::MapMetro::Dev> - Map::Metro development tools
226              
227             =item *
228              
229             L<Map::Metro::Plugin::Map::Barcelona::Lines> - An example
230              
231             =item *
232              
233             L<Map::Metro>
234              
235             =item *
236              
237             L<Map::Metro::Plugin::Map>
238              
239             =back
240              
241             =head1 SOURCE
242              
243             L<https://github.com/Csson/p5-Dist-Zilla-Plugin-MapMetro-MakeLinePod>
244              
245             =head1 HOMEPAGE
246              
247             L<https://metacpan.org/release/Dist-Zilla-Plugin-MapMetro-MakeLinePod>
248              
249             =head1 AUTHOR
250              
251             Erik Carlsson <info@code301.com>
252              
253             =head1 COPYRIGHT AND LICENSE
254              
255             This software is copyright (c) 2015 by Erik Carlsson <info@code301.com>.
256              
257             This is free software; you can redistribute it and/or modify it under
258             the same terms as the Perl 5 programming language system itself.
259              
260             =cut