File Coverage

blib/lib/Story/Interact/Analyze.pm
Criterion Covered Total %
statement 23 76 30.2
branch 0 18 0.0
condition 0 13 0.0
subroutine 8 11 72.7
pod 0 1 0.0
total 31 119 26.0


line stmt bran cond sub pod time code
1 5     5   87 use 5.010001;
  5         19  
2 5     5   28 use strict;
  5         9  
  5         116  
3 5     5   26 use warnings;
  5         8  
  5         317  
4              
5             package Story::Interact::Analyze;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.001013';
9              
10 5     5   2100 use Story::Interact::State;
  5         24  
  5         206  
11              
12 5     5   39 use Moo;
  5         15  
  5         34  
13 5     5   5294 use Storable qw( dclone );
  5         17714  
  5         369  
14 5     5   79 use Types::Common -types;
  5         13  
  5         70  
15 5     5   68188 use namespace::clean;
  5         16  
  5         45  
16              
17             has 'page_source' => (
18             is => 'ro',
19             isa => Object,
20             required => 1,
21             );
22              
23             has 'data' => (
24             is => 'lazy',
25             init_arg => undef,
26             builder => 1,
27             );
28              
29             sub _build_data {
30 0     0     my ( $self ) = @_;
31            
32 0           my @page_ids = $self->page_source->all_page_ids;
33 0           my %data;
34            
35             # Allow the `main` page to define NPCs, etc, first.
36 0           my $state = Story::Interact::State->new;
37 0           $self->page_source->get_page( $state, 'main' );
38            
39 0           for my $page_id ( @page_ids ) {
40 0           $data{$page_id}{exists} = 1;
41            
42 0 0         my $page_source = $self->page_source->get_source_code( $page_id ) or next;
43 0           my @naive_links;
44 0           while ( $page_source =~ /^ \s* next_page \s* \(? \s* (\S+) \s* [,=] /mxg ) {
45 0           push @naive_links, $1;
46             }
47 0 0         @naive_links = map { /\A\w+\z/ ? $1 : scalar( eval $_ ) } @naive_links;
  0            
48            
49 0           my $naive_todo = 0;
50 0 0         if ( $page_source =~ /^ \s* todo \b /mx ) {
51 0           $naive_todo = 1;
52             }
53            
54 0           my ( @explicit_links, $explicit_todo );
55 0           my $cloned_state = dclone( $state );
56 0 0         if ( my $page = eval { $self->page_source->get_page( $cloned_state, $page_id ) } ) {
  0            
57 0           @explicit_links = map $_->[0], @{ $page->next_pages };
  0            
58 0           $explicit_todo = 0+!! $page->todo;
59 0           $data{$page_id}{abstract} = $page->abstract;
60 0           $data{$page_id}{location} = $page->location;
61             }
62             else {
63 0           $data{$page_id}{error} = 1;
64             }
65            
66 0           my @all_links = do {
67 0           my %tmp;
68 0           $tmp{$_}++ for @explicit_links;
69 0           $tmp{$_}++ for @naive_links;
70 0           keys %tmp;
71             };
72            
73 0   0       $data{$page_id}{todo} = $explicit_todo // $naive_todo;
74 0           $data{$page_id}{outgoing} = \@all_links;
75 0   0       $data{$page_id}{incoming} //= [];
76 0           for my $link_id ( @all_links ) {
77 0   0       $data{$link_id} //= { exists => 0 };
78 0   0       $data{$link_id}{incoming} //= [];
79 0           push @{ $data{$link_id}{incoming} }, $page_id;
  0            
80             }
81             }
82            
83 0           \%data;
84             }
85              
86             sub _quote {
87 0     0     my ( $str ) = @_;
88 0           $str =~ s/"/""/g;
89 0           qq{"$str"};
90             }
91              
92             sub to_tabbed {
93 0     0 0   my ( $self ) = @_;
94 0           my $data = $self->data;
95 0           my $out = '';
96            
97 0           $out .= join(
98             "\t",
99             'Page Id',
100             'Not Found',
101             'Errors',
102             'Todo',
103             'Abstract',
104             'Location',
105             'Outgoing Links',
106             'Incoming Links',
107             ) . "\n";
108            
109 0           for my $page_id ( sort keys %$data ) {
110 0           my $d = $data->{$page_id};
111             $out .= join(
112             "\t",
113             $page_id,
114             $d->{exists} ? '' : 'not found',
115             $d->{error} ? 'error' : '',
116             $d->{todo} ? 'todo' : '',
117             _quote( $d->{abstract} // '?' ),
118             _quote( $d->{location} // '?' ),
119 0 0         join( q{;}, sort @{ $d->{outgoing} || [] } ),
120 0 0 0       join( q{;}, sort @{ $d->{incoming} || [] } ),
  0 0 0        
    0          
    0          
121             ) . "\n";
122             }
123            
124 0           return $out;
125             }
126              
127             1;
128