File Coverage

lib/Book/Bilingual/File.pm
Criterion Covered Total %
statement 63 63 100.0
branch 5 8 62.5
condition n/a
subroutine 13 13 100.0
pod 1 1 100.0
total 82 85 96.4


line stmt bran cond sub pod time code
1             package Book::Bilingual::File;
2             # ABSTRACT: Construct a Bilingual book from file
3 2     2   59940 use Mojo::Base -base;
  2         160148  
  2         10  
4 2     2   767 use Book::Bilingual;
  2         4  
  2         12  
5 2     2   718 use Book::Bilingual::Dline;
  2         4  
  2         14  
6 2     2   656 use Book::Bilingual::Dlineset;
  2         5  
  2         12  
7 2     2   671 use Book::Bilingual::Chapter;
  2         4  
  2         12  
8 2     2   1536 use Path::Tiny qw/path/;
  2         18976  
  2         151  
9 2     2   19 use Carp;
  2         3  
  2         1739  
10              
11             has 'book' => sub { Book::Bilingual->new}; # Book::Bilingual
12             has 'file'; # Path to file
13             has 'chapters'; # Arrayref of chapter text
14              
15             sub new { ## ($path :Path)
16 21 50   21 1 3502 croak 'Need args ($path)' unless @_ > 1;
17 21         77 my $self = $_[0]->SUPER::new({ file => path($_[1]) });
18 21         664 $self->_init();
19             }
20              
21             sub _init {
22 21     21   41 my ($self) = @_;
23             #say ref $self->book;
24              
25 21         85 my $text = $self->file->slurp_utf8;
26 21         7487 $self->chapters( _extract_chapters($text));
27              
28 21         132 foreach my $chapter (@{$self->chapters}) {
  21         48  
29              
30             # Generate Dlinesets from extracted chapter text
31             my @Dsets = map {
32 189         1036 Book::Bilingual::Dlineset->new->set(_extract_dlines($_));
33 42         108 } @{_extract_dlineset($chapter)};
  42         78  
34              
35 42         424 my $book_chapter = Book::Bilingual::Chapter->new;
36 42         341 $book_chapter->number(shift @Dsets);
37 42         293 $book_chapter->title(shift @Dsets);
38 42         239 $book_chapter->body([@Dsets]);
39 42         223 $self->book->push($book_chapter);
40             };
41              
42 21         150 return $self;
43             }
44             sub _extract_chapters { ## ($file_text) :> [$chapter_text]
45 21     21   65 my ($text) = @_;
46              
47 21         1237 my @chapters = split /^----$/m, $text;
48 21 50       80 shift @chapters if scalar @chapters; # Ignore TOC and other front matter
49              
50 21         109 return [@chapters];
51             }
52             =head2 _extract_dlineset
53              
54             Returns arrayref of DSET_TEXT.
55              
56             Sample of DSET_TEXT:
57              
58             Chapter One
59             #chapter-number <-- class definition
60              
61             บทที่หนึ่ง /
62             บทที่ /One
63             /Chapter One
64             .. <-- last line
65              
66              
67             =cut
68             sub _extract_dlineset { ## ($chapter_text) :> [DSET_TEXT]
69 45     45   73 my ($chapter) = @_;
70              
71             my @dsets = grep {
72 45         2008 $_ !~ /^#/ # Ignore comments
  852         1233  
73             } split /^__ /m, $chapter;
74              
75 45 50       141 shift @dsets if scalar @dsets; # Ignore chapter front matter
76              
77 45         117 return [@dsets];
78             }
79             =head2 _extract_dlines
80              
81             A set with class definition
82              
83             Chapter One
84             #chapter-number <-- class definition
85              
86             บทที่หนึ่ง /
87             บทที่ /One
88             /Chapter One
89             .. <-- last line
90              
91             A set without the class definition
92              
93             "Can we go to Polseath as usual?"
94              
95             "เราไปชายหาดตามปกติได้ไหม" /
96             /"Can /เราไปชายหาดตามปกติ?"
97             /"Can /เราไป /beach as usual?"
98             /"Can /เรา /go to the beach as usual?"
99             /"Can we go to the beach as usual?"
100             .. <-- last line
101              
102             =cut
103             sub _extract_dlines { ## ($dset_text) :> [Dline]
104 191     191   1229 my ($dset) = @_;
105 191         1412 my @lines = split "\n", $dset;
106              
107 191         213 shift @lines; # Ignore first line
108 191         286 my $class = _extract_class(shift @lines); # Extract dline class
109 191         218 pop @lines; # Ignore last line
110              
111             @lines = grep {
112 191         226 $_ !~ /^\s*$/; # Ignore empty lines
  1205         2183  
113             } @lines;
114              
115             @lines = map {
116 191         222 $_ =~ s/^ //; # Trim prefix
  1077         7694  
117 1077         2602 Book::Bilingual::Dline->new({ class=>$class, str=>$_ });
118             } @lines;
119              
120 191         1684 return [@lines];
121             }
122             sub _extract_class {
123 194     194   1586 my ($line) = @_;
124              
125 194         761 $line =~ s/^\s+|\s+$//g; # Trim front and back
126 194 100       332 return '' unless $line;
127              
128 130         300 $line =~ s/#//g; # Remove # markers
129 130         428 return join ' ',(split /\s+/, $line); # Split and recombine words
130             }
131              
132             1;