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 $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 my @events = $obj->events; # array my $events = $obj->events; # arrayref $obj->events([$e1, $e2, $e3]); Access to subtitle events =head2 C $obj->sort_events; Internally sort events by start time (ascending) =head2 C =head2 C Stubs for subclasses. Should return -1 on error, >= 0 on success (parsed events count). =head2 C my $cnt = $obj->from_string($text); Parse subtitle from given string. Return codes are the same as C =head2 C my $cnt = $obj->from_file($path); Parse subtitle from given file. Return codes are the same as C =cut