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   59145 use Mojo::Base -base;
  2         162254  
  2         11  
4 2     2   639 use Book::Bilingual;
  2         3  
  2         10  
5 2     2   638 use Book::Bilingual::Dline;
  2         4  
  2         11  
6 2     2   590 use Book::Bilingual::Dlineset;
  2         3  
  2         12  
7 2     2   639 use Book::Bilingual::Chapter;
  2         4  
  2         12  
8 2     2   1433 use Path::Tiny qw/path/;
  2         17476  
  2         116  
9 2     2   14 use Carp;
  2         11  
  2         1787  
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 20 50   20 1 3091 croak 'Need args ($path)' unless @_ > 1;
17 20         43 my $self = $_[0]->SUPER::new({ file => path($_[1]) });
18 20         574 $self->_init();
19             }
20              
21             sub _init {
22 20     20   27 my ($self) = @_;
23             #say ref $self->book;
24              
25 20         38 my $text = $self->file->slurp_utf8;
26 20         5215 $self->chapters( _extract_chapters($text));
27              
28 20         100 foreach my $chapter (@{$self->chapters}) {
  20         33  
29              
30             # Generate Dlinesets from extracted chapter text
31             my @Dsets = map {
32 180         863 Book::Bilingual::Dlineset->new->set(_extract_dlines($_));
33 40         82 } @{_extract_dlineset($chapter)};
  40         52  
34              
35 40         309 my $book_chapter = Book::Bilingual::Chapter->new;
36 40         295 $book_chapter->number(shift @Dsets);
37 40         198 $book_chapter->title(shift @Dsets);
38 40         198 $book_chapter->body([@Dsets]);
39 40         184 $self->book->push($book_chapter);
40             };
41              
42 20         115 return $self;
43             }
44             sub _extract_chapters { ## ($file_text) :> [$chapter_text]
45 20     20   36 my ($text) = @_;
46              
47 20         1100 my @chapters = split /^----$/m, $text;
48 20 50       52 shift @chapters if scalar @chapters; # Ignore TOC and other front matter
49              
50 20         86 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 43     43   65 my ($chapter) = @_;
70              
71             my @dsets = grep {
72 43         1836 $_ !~ /^#/ # Ignore comments
  816         1067  
73             } split /^__ /m, $chapter;
74              
75 43 50       111 shift @dsets if scalar @dsets; # Ignore chapter front matter
76              
77 43         99 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 182     182   1140 my ($dset) = @_;
105 182         970 my @lines = split "\n", $dset;
106              
107 182         182 shift @lines; # Ignore first line
108 182         223 my $class = _extract_class(shift @lines); # Extract dline class
109 182         199 pop @lines; # Ignore last line
110              
111             @lines = grep {
112 182         202 $_ !~ /^\s*$/; # Ignore empty lines
  1148         1867  
113             } @lines;
114              
115             @lines = map {
116 182         199 $_ =~ s/^ //; # Trim prefix
  1026         6978  
117 1026         2341 Book::Bilingual::Dline->new({ class=>$class, str=>$_ });
118             } @lines;
119              
120 182         1439 return [@lines];
121             }
122             sub _extract_class {
123 185     185   1496 my ($line) = @_;
124              
125 185         669 $line =~ s/^\s+|\s+$//g; # Trim front and back
126 185 100       311 return '' unless $line;
127              
128 124         236 $line =~ s/#//g; # Remove # markers
129 124         365 return join ' ',(split /\s+/, $line); # Split and recombine words
130             }
131              
132             1;