diff --git a/src/Code/Converters/SubMicroDvdConverter.php b/src/Code/Converters/SubMicroDvdConverter.php index 53d46cc..1d34971 100644 --- a/src/Code/Converters/SubMicroDvdConverter.php +++ b/src/Code/Converters/SubMicroDvdConverter.php @@ -2,34 +2,42 @@ namespace Done\Subtitles\Code\Converters; +use Done\Subtitles\Code\Helpers; + class SubMicroDvdConverter implements ConverterContract { static protected $fps = 23.976; // SubtitleEdit by default uses this fps. Taken that value without much thinking. Change it to a better values if you will find. + + static $pattern = '/(?:\{|\[)(?\d+)(?:\}|\])(?:\{|\[)(?\d+)(?:\}|\])(?.+)/'; public function canParseFileContent($file_content) { - $pattern = "/\{\d+\}\{\d+\}(.*)/"; - return preg_match($pattern, $file_content, $matches); + return preg_match(self::$pattern, $file_content, $matches); } public function fileContentToInternalFormat($file_content, $original_file_content) { $fps = self::$fps; - $pattern = "/\{(\d+)\}\{(\d+)\}(\{.*\})?(.+)/"; - preg_match_all($pattern, $file_content, $blocks, PREG_SET_ORDER); + preg_match_all(self::$pattern, $file_content, $blocks, PREG_SET_ORDER); $internal_format = []; foreach ($blocks as $k => $block) { - if ($k === 0 && is_numeric($block[4])) { - $fps = $block[4]; + if ($k === 0 && is_numeric($block['text'])) { + $fps = $block['text']; continue; } + $lines = explode("|", $block['text']); + foreach ($lines as &$line) { + $line = Helpers::strAfterLast($line, '}'); + } + unset($line); + $internal_format[] = [ - 'start' => static::timeToInternal($block[1], $fps), - 'end' => static::timeToInternal($block[2], $fps), - 'lines' => explode("|", $block[4]), + 'start' => static::timeToInternal($block['start'], $fps), + 'end' => static::timeToInternal($block['end'], $fps), + 'lines' => $lines, ]; } return $internal_format; diff --git a/src/Code/Helpers.php b/src/Code/Helpers.php index 31dc071..e26fde4 100644 --- a/src/Code/Helpers.php +++ b/src/Code/Helpers.php @@ -238,4 +238,19 @@ public static function mb_wordwrap($string, $width = 75, $break = "\n", $cut = f return $result; } + + public static function strAfterLast($subject, $search) + { + if ($search === '') { + return $subject; + } + + $position = strrpos($subject, (string) $search); + + if ($position === false) { + return $subject; + } + + return substr($subject, $position + strlen($search)); + } } diff --git a/tests/files/sub_microdvd_with_styles.sub b/tests/files/sub_microdvd_with_styles.sub index 5ededf9..5e422dd 100644 --- a/tests/files/sub_microdvd_with_styles.sub +++ b/tests/files/sub_microdvd_with_styles.sub @@ -1,2 +1,2 @@ -{3294}{3366}Senator, we're making|our final approach into Coruscant. +{3294}{3366}Senator, we're making|{y:i}our final approach into Coruscant. {89682}{89730}{c:$0000ff}{y:b,u}{f:DeJaVuSans}{s:12}Very good, Lieutenant. \ No newline at end of file diff --git a/tests/formats/SubMicroDvdTest.php b/tests/formats/SubMicroDvdTest.php index 6d88ab8..cbe1686 100644 --- a/tests/formats/SubMicroDvdTest.php +++ b/tests/formats/SubMicroDvdTest.php @@ -64,4 +64,14 @@ public function testUsesSpecifiedFps() $expected = (new Subtitles())->add(1, 2, 'Subtitle line 2')->getInternalFormat(); $this->assertInternalFormatsEqual($expected, $actual); } + + public function testParsesSquareBrackets() + { + $content = <<getInternalFormat(); + $expected = (new Subtitles())->add(0, 4.17, 'text')->getInternalFormat(); + $this->assertInternalFormatsEqual($expected, $actual); + } }