File Coverage

blib/lib/Story/Interact/Harness/Terminal.pm
Criterion Covered Total %
statement 26 80 32.5
branch 0 12 0.0
condition 0 2 0.0
subroutine 9 16 56.2
pod 0 4 0.0
total 35 114 30.7


line stmt bran cond sub pod time code
1 5     5   146 use 5.010001;
  5         22  
2 5     5   35 use strict;
  5         11  
  5         122  
3 5     5   29 use warnings;
  5         12  
  5         340  
4              
5             package Story::Interact::Harness::Terminal;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.001013';
9              
10 5     5   2236 use Story::Interact::Harness ();
  5         20  
  5         219  
11 5     5   3640 use Term::Choose qw( choose );
  5         575390  
  5         851  
12 5     5   3301 use Text::Wrap ();
  5         15529  
  5         189  
13              
14 5     5   43 use Moo;
  5         15  
  5         153  
15 5     5   3574 use Types::Common -types;
  5         15  
  5         158  
16 5     5   84900 use namespace::clean;
  5         35  
  5         356  
17              
18             with 'Story::Interact::Harness';
19              
20             has 'paragraph_formatter' => (
21             is => 'ro',
22             isa => CodeRef,
23             builder => 1,
24             );
25              
26             if ( Story::Interact::Harness::DEBUG ) {
27             around get_page => sub {
28             my ( $next, $self ) = ( shift, shift );
29             my $page = $self->$next( @_ );
30             if ( @{ $page->next_pages } > 0 ) {
31             $page->add_next_page( ':debug', 'DEBUG INTERFACE' );
32             }
33             return $page;
34             };
35             }
36              
37             sub run {
38 0     0 0   my ( $self ) = @_;
39              
40 0           my $page = $self->get_page( Story::Interact::Harness::FIRST_PAGE );
41              
42 0           while ( 1 ) {
43 0           $self->display_page( $page );
44 0 0         my $chosen = $self->prompt_next( $page ) or last;
45 0           if ( Story::Interact::Harness::DEBUG and $chosen eq ':debug' ) {
46             $page = $self->run_debugger( $page );
47             next;
48             }
49 0           $page = $self->get_page( $chosen );
50             }
51             }
52              
53             sub display_page {
54 0     0 0   my ( $self, $page ) = @_;
55 0           my $f = $self->paragraph_formatter;
56 0           for my $paragraph ( @{ $page->text } ) {
  0            
57 0           print $f->( $paragraph ), "\n\n";
58             }
59             }
60              
61             sub prompt_next {
62 0     0 0   my ( $self, $page ) = @_;
63              
64 0           my @next = @{ $page->next_pages };
  0            
65              
66 0 0         if ( @next == 0 ) {
67 0           print ">> Finished!\n\n";
68 0           return undef;
69             }
70              
71 0           my @descs = map { $_->[1] } @next;
  0            
72              
73 0 0         if ( @next == 1 ) {
74 0           choose( \@descs, { index => 1, layout => 2, prompt => '' } );
75 0           print ">> ", $descs[0], "\n\n";
76 0           return $next[0][0];
77             }
78             else {
79 0           my $got = choose( \@descs, { index => 1, layout => 2, prompt => 'Next?' } );
80 0 0         defined $got or return undef;
81 0           print ">> ", $descs[$got], "\n\n";
82 0           return $next[$got][0];
83             }
84             }
85              
86             sub _build_paragraph_formatter {
87 0     0     my ( $self ) = @_;
88 0 0         if ( eval "use String::Tagged::Markdown; use String::Tagged::Terminal; 1" ) {
89             return sub {
90 0     0     my ( $p ) = @_;
91 0           my $st = String::Tagged::Markdown->parse_markdown( $p );
92 0           my $fmt = String::Tagged::Terminal->new_from_formatting( $st->as_formatting );
93 0           my $term = $fmt->build_terminal( no_color => $ENV{NO_COLOR} );
94 0           local $Text::Wrap::columns = 78;
95 0           return Text::Wrap::wrap( q{}, q{}, $term ); # Gasp!
96 0           };
97             }
98             return sub {
99 0     0     my ( $p ) = @_;
100 0           local $Text::Wrap::columns = 78;
101 0           Text::Wrap::wrap( q{}, q{}, $p );
102 0           };
103             }
104              
105             # Useful for debugging. I'm sure a better debugger is possible.
106             sub run_debugger {
107 0     0 0   my ( $self, $page ) = @_;
108 0           print "Next page options: \n";
109 0           print "Now entering DEBUG mode.\n";
110 0           Story::Interact::Syntax::START( $self->state, ':debug' );
111 0           for my $next ( @{ $page->next_pages } ) {
  0            
112 0   0       Story::Interact::Syntax::next_page( $next->[0], $next->[1], %{ $next->[2] // {} } );
  0            
113             }
114 0 0         if ( $page->has_location ) {
115 0           Story::Interact::Syntax::at( $page->location );
116             }
117 0           while ( my $line = <> ) {
118 0           Story::Interact::Syntax::DEBUG( $line );
119             }
120 0           return Story::Interact::Syntax::FINISH();
121             }
122              
123             1;