You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
2.6 KiB

package Subtitle::Format;
use strict;
use warnings;
use utf8;
use Subtitle::Utils 'strip_bom';
sub log {
my ($self, $level, $msg) = @_;
if ($level eq 'error') {
push @{ $self->{log} }, "E: $msg";
} elsif ($level eq 'warn') {
push @{ $self->{log} }, "W: $msg";
} elsif ($level eq 'info') {
push @{ $self->{log} }, "I: $msg";
} elsif ($level eq 'debug') {
push @{ $self->{log} }, "D: $msg" if $self->{debug};
} else {
warn "Unknown loglevel $level of $msg\n";
}
return 1;
}
sub parse { return "Unimplemented by subclass"; }
sub build { return "Unimplemented by subclass"; }
sub events {
my ($self, $events) = @_;
if ($events and ref($events) eq 'ARRAY') {
$self->{events} = $events;
}
return wantarray ? @{ $self->{events} } : $self->{events};
}
sub sort_events {
my ($self) = @_;
my @sorted = sort {
$a->t_start <=> $b->t_start
} @{ $self->events; };
$self->events(\@sorted);
}
sub from_string {
my ($self, $text) = @_;
my @lines = split /\r?\n/o, $text;
return $self->parse(\@lines);
}
sub from_file {
my ($self, $path) = @_;
open my $FH, '<', $path
or return $self->log(error => "can't open file: $path -- $!");
my @lines = <$FH>;
close $FH;
return unless @lines; # empty file?
strip_bom($lines[0]);
return $self->parse(\@lines);
}
sub to_string {
my ($self) = @_;
return $self->build;
}
sub to_file {
my ($self, $path) = @_;
open my $FH, '>', $path
or return $self->log(error => "can't open file: $path -- $!");
print $FH $self->build;
close $FH;
return 1;
}
1;
=pod
=head1 NAME
Subtitle::Format - base class of subtitle file
=head1 SYNOPSYS
use base 'Subtitle::Format';
This module should not be used directly.
=head1 METHODS
=head2 C<log>
$obj->log(warn => "something happens");
Add some info to processing log.
Takes two args: message level (debug/info/warn/error) and message text
Collected messages can be accessed like this:
my @log = @{ $obj->{log} };
=head2 C<events>
my @events = $obj->events; # array
my $events = $obj->events; # arrayref
$obj->events([$e1, $e2, $e3]);
Access to subtitle events
=head2 C<sort_events>
$obj->sort_events;
Internally sort events by start time (ascending)
=head2 C<build>
=head2 C<parse>
Stubs for subclasses.
Should return -1 on error, >= 0 on success (parsed events count).
=head2 C<from_string>
my $cnt = $obj->from_string($text);
Parse subtitle from given string.
Return codes are the same as C<parse>
=head2 C<from_file>
my $cnt = $obj->from_file($path);
Parse subtitle from given file.
Return codes are the same as C<parse>
=cut