diff --git a/lib/Subtitle/Format/SRT.pm b/lib/Subtitle/Format/SRT.pm index c9b5ad8..5344d92 100644 --- a/lib/Subtitle/Format/SRT.pm +++ b/lib/Subtitle/Format/SRT.pm @@ -4,6 +4,7 @@ use strict; use warnings; use utf8; +use Subtitle::Event; use Subtitle::Utils qw(:string :timing); use base 'Subtitle::Format'; @@ -11,9 +12,8 @@ use base 'Subtitle::Format'; sub new { my ($class, %args) = @_; my $self = { - debug => 0, - eol => "\n", - %args, + debug => $args{debug} || 0, + eol => $args{eol} || "\n", events => [], log => [], timing_fmt => "%02d:%02d:%02d,%03d", @@ -22,7 +22,7 @@ sub new { return bless($self, $class); } -sub new_event { return +{ id => undef, timing => undef, text => undef }; } +sub new_event { return Subtitle::Event->new; } sub parse { my ($self, $lines) = @_; @@ -41,25 +41,26 @@ sub parse { next; } # expected: timing - if ($line and $event and not $event->{timing}) { + if ($line and $event and not ($event->t_start or $event->t_end)) { $self->log(debug => "Expecting timing line at $linenum"); - my $timing = []; + my @t; my ($start, $end, $rest) = ($line =~ m/(\S+)\s*-->\s*(\S+)(.*)/o); unless ($start and $end) { $self->log(warn => "Expected timing but found `$line` at $linenum, skipped"); next; } - $timing->[0] = parse_timing($start); - unless ($timing->[0] >= 0) { + $t[0] = parse_timing($start); + unless ($t[0] >= 0) { $self->log(warn => "Can't parse timing at line $linenum: $start"); next; } - $timing->[1] = parse_timing($end); - unless ($timing->[1] >= 0) { + $t[1] = parse_timing($end); + unless ($t[1] >= 0) { $self->log(warn => "Can't parse timing at line $linenum: $end"); next; } - $event->{timing} = $timing; + $event->t_start($t[0]); + $event->t_end ($t[1]); trim($rest); next unless $rest; # extension: timing @@ -102,17 +103,18 @@ sub parse { next; } # expected: event text - if ($line and $event and $event->{timing}) { + if ($line and $event and ($event->t_start or $event->t_end)) { trim($line); $self->log(debug => "Text line at $linenum -> append"); - $event->{text} //= ''; - $event->{text} .= $self->{eol} if $event->{text}; - $event->{text} .= $line; + my $text = $event->text; + $text .= $self->{eol} if $text; + $text .= $line; + $event->text($text); next; } } # foreach @lines # finalize last event - if ($event and $event->{timing} and $event->{text}) { + if ($event and $event->text and ($event->t_start or $event->t_end)) { push @{ $self->{events} }, $event; } @@ -125,12 +127,10 @@ sub build { foreach my $e (@{ $self->{events} }) { push @lines, $e->{id}; - my $start = sprintf $self->{timing_fmt}, - make_timing($e->{timing}->[0]); - my $end = sprintf $self->{timing_fmt}, - make_timing($e->{timing}->[1]); - push @lines, sprintf("%s --> %s", $start, $end); - push @lines, $e->{text}; + my $start = sprintf $self->{timing_fmt}, make_timing($e->t_start); + my $end = sprintf $self->{timing_fmt}, make_timing($e->t_end); + push @lines, sprintf "%s --> %s", $start, $end; + push @lines, $e->text; push @lines, ""; } diff --git a/lib/Subtitle/Format/SSA/Event.pm b/lib/Subtitle/Format/SSA/Event.pm index 3cc2e67..316f62d 100644 --- a/lib/Subtitle/Format/SSA/Event.pm +++ b/lib/Subtitle/Format/SSA/Event.pm @@ -4,7 +4,7 @@ use strict; use warnings; use utf8; -use base 'Subtitle::Format::SSA::Record'; +use base qw(Subtitle::Event Subtitle::Format::SSA::Record); my @FIELDS_SSA = qw(marked start end style name marginl marginr marginv effect text); my @FIELDS_ASS = qw(layer start end style name marginl marginr marginv effect text); diff --git a/t/format-srt.t b/t/format-srt.t index 073d7ff..c2f9e45 100644 --- a/t/format-srt.t +++ b/t/format-srt.t @@ -7,7 +7,7 @@ use Subtitle::Format::SRT; my $srt = Subtitle::Format::SRT->new(debug => 1); is(ref $srt, 'Subtitle::Format::SRT'); -can_ok($srt, qw(new parse)); +can_ok($srt, qw(new parse build)); my $sample = <<"EOF"; 1 @@ -25,11 +25,11 @@ my $cnt = $srt->from_string($sample); is($cnt, 2); my @events = @{ $srt->{events} }; -is($events[0]->{timing}->[0], 0.1); -is($events[0]->{timing}->[1], 8.0); -is($events[0]->{text}, "kirari hikaru yume o taisetsu ni dakishimete\n"); -is($events[1]->{timing}->[0], 8.1); -is($events[1]->{timing}->[1], 12.0); -is($events[1]->{text}, "ippo dzutsu aruite yukou\n"); +is($events[0]->t_start, 0.1); +is($events[0]->t_end, 8.0); +is($events[0]->text, "kirari hikaru yume o taisetsu ni dakishimete\n"); +is($events[1]->t_start, 8.1); +is($events[1]->t_end, 12.0); +is($events[1]->text, "ippo dzutsu aruite yukou\n"); exit 0;