diff options
Diffstat (limited to 'srt2vtt')
-rw-r--r-- | srt2vtt/subrip.scm | 66 | ||||
-rw-r--r--[-rwxr-xr-x] | srt2vtt/ui.scm (renamed from srt2vtt) | 112 | ||||
-rw-r--r-- | srt2vtt/webvtt.scm | 45 |
3 files changed, 124 insertions, 99 deletions
diff --git a/srt2vtt/subrip.scm b/srt2vtt/subrip.scm new file mode 100644 index 0000000..167aff8 --- /dev/null +++ b/srt2vtt/subrip.scm @@ -0,0 +1,66 @@ +;;; srt2vtt --- SRT to WebVTT converter +;;; Copyright © 2015 David Thompson <davet@gnu.org> +;;; +;;; srt2vtt is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or +;;; (at your option) any later version. +;;; +;;; srt2vtt is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with srt2vtt. If not, see <http://www.gnu.org/licenses/>. + +(define-module (srt2vtt subrip) + #:use-module (ice-9 match) + #:use-module (ice-9 rdelim) + #:use-module (ice-9 regex) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-11) + #:use-module (srfi srfi-26) + #:use-module (srt2vtt) + #:export (read-subrip + read-subrips)) + +(define parse-time + (let ((regexp (make-regexp "([0-9]+):([0-9]+):([0-9]+),([0-9]+)"))) + (lambda (s) + "Parse the SubRip formatted timestamp in the string S into a 4 +element list. Valid input looks like '00:00:03.417'." + (let ((match (regexp-exec regexp s))) + (map (cut match:substring match <>) '(1 2 3 4)))))) + +(define parse-time-span + (let ((regexp (make-regexp "([0-9:,]+) --> ([0-9:,]+)"))) + (lambda (s) + "Parse the SubRip formatted time span in the string S and return +two values: the start time and the end time. Valid input looks like +'00:00:03.417 --> 00:00:04.936'." + (let ((match (regexp-exec regexp s))) + (values (parse-time (match:substring match 1)) + (parse-time (match:substring match 2))))))) + +(define (read-subrip port) + "Read a SubRip formatted subtitle from PORT." + (let-values (((id) (string->number (read-line port))) + ((start end) (parse-time-span (read-line port))) + ((lines) (let loop ((lines '())) + (let ((line (read-line port))) + (if (or (eof-object? line) + (and (string-null? line) + ;; A subtitle may be a blank line! + (not (null? lines)))) + lines + (loop (cons line lines))))))) + (make-subtitle id start end lines))) + +(define (read-subrips port) + "Read all SubRip formatted subtitles from PORT." + (reverse + (let loop ((subs '())) + (if (eof-object? (peek-char port)) + subs + (loop (cons (read-subrip port) subs)))))) diff --git a/srt2vtt b/srt2vtt/ui.scm index a4cb576..607c49e 100755..100644 --- a/srt2vtt +++ b/srt2vtt/ui.scm @@ -1,7 +1,3 @@ -#!/usr/bin/guile --*- scheme -*- -!# - ;;; srt2vtt --- SRT to WebVTT converter ;;; Copyright © 2015 David Thompson <davet@gnu.org> ;;; @@ -18,97 +14,14 @@ ;;; You should have received a copy of the GNU General Public License ;;; along with srt2vtt. If not, see <http://www.gnu.org/licenses/>. -;;; Commentary: -;; -;; Convert SRT formatted subtitles to WebVTT format. -;; -;;; Code: - -(use-modules (ice-9 format) - (ice-9 match) - (ice-9 rdelim) - (ice-9 regex) - (srfi srfi-1) - (srfi srfi-9) - (srfi srfi-11) - (srfi srfi-26) - (srfi srfi-37)) - -(define-record-type <subtitle> - (make-subtitle id start end text) - subtitle? - (id subtitle-id) - (start subtitle-start) - (end subtitle-end) - (text subtitle-text)) - -(define parse-time - (let ((regexp (make-regexp "([0-9]+):([0-9]+):([0-9]+),([0-9]+)"))) - (lambda (s) - "Parse the SubRip formatted timestamp in the string S into a 4 -element list. Valid input looks like '00:00:03.417'." - (let ((match (regexp-exec regexp s))) - (map (cut match:substring match <>) '(1 2 3 4)))))) - -(define parse-time-span - (let ((regexp (make-regexp "([0-9:,]+) --> ([0-9:,]+)"))) - (lambda (s) - "Parse the SubRip formatted time span in the string S and return -two values: the start time and the end time. Valid input looks like -'00:00:03.417 --> 00:00:04.936'." - (let ((match (regexp-exec regexp s))) - (values (parse-time (match:substring match 1)) - (parse-time (match:substring match 2))))))) - -(define (read-sub-rip port) - "Read a SubRip formatted subtitle from PORT." - (let-values (((id) (string->number (read-line port))) - ((start end) (parse-time-span (read-line port))) - ((lines) (let loop ((lines '())) - (let ((line (read-line port))) - (if (or (eof-object? line) - (and (string-null? line) - ;; A subtitle may be a blank line! - (not (null? lines)))) - lines - (loop (cons line lines))))))) - (make-subtitle id start end lines))) - -(define (read-sub-rips port) - "Read all SubRip formatted subtitles from PORT." - (reverse - (let loop ((subs '())) - (if (eof-object? (peek-char port)) - subs - (loop (cons (read-sub-rip port) subs)))))) - -(define (write-time time port) - "Write TIME as a WebVTT formatted timestamp to PORT." - (match time - ((h m s ms) - (format port "~a:~a:~a.~a" h m s ms)))) - -(define (write-web-vtt subtitle port) - "Write SUBTITLE as a WebVTT formatted subtitle to PORT." - (match subtitle - (($ <subtitle> id start end text) - (format port "~a~%" id) - (write-time start port) - (display " --> " port) - (write-time end port) - (newline port) - (format port "~a~%" (string-join text "\n")) - (newline port)))) - -(define (write-web-vtts subtitles port) - "Write all SUBTITLES as WebVTT formatted subtitles to PORT." - (format port "WEBVTT~%~%") - (for-each (cut write-web-vtt <> port) subtitles)) - -(define (convert input-port output-port) - "Read the SubRip formatted subtitles from INPUT-PORT and write the -WebVTT equivalents to OUTPUT-PORT." - (write-web-vtts (read-sub-rips input-port) output-port)) +(define-module (srt2vtt ui) + #:use-module (ice-9 format) + #:use-module (ice-9 match) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-37) + #:use-module (srt2vtt subrip) + #:use-module (srt2vtt webvtt) + #:export (main)) (define (show-help-and-exit) (format #t "Usage: srt2vtt [OPTIONS] @@ -184,6 +97,11 @@ When an option isn't specified in ARGS, it defaults to the value in (error "Extraneous argument '~a'" arg)) %default-args)) +(define (convert input-port output-port) + "Read the SubRip formatted subtitles from INPUT-PORT and write the +WebVTT equivalents to OUTPUT-PORT." + (write-webvtts (read-subrips input-port) output-port)) + (define (main args) "srt2vtt entry point." (let ((opts (parse-opts args))) @@ -192,7 +110,3 @@ When an option isn't specified in ARGS, it defaults to the value in (call-with-port-or-output-file (assoc-ref opts 'output) (lambda (output-port) (convert input-port output-port))))))) - -(match (command-line) - ((arg0 args ...) - (main args))) diff --git a/srt2vtt/webvtt.scm b/srt2vtt/webvtt.scm new file mode 100644 index 0000000..f4cd91b --- /dev/null +++ b/srt2vtt/webvtt.scm @@ -0,0 +1,45 @@ +;;; srt2vtt --- SRT to WebVTT converter +;;; Copyright © 2015 David Thompson <davet@gnu.org> +;;; +;;; srt2vtt is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or +;;; (at your option) any later version. +;;; +;;; srt2vtt is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with srt2vtt. If not, see <http://www.gnu.org/licenses/>. + +(define-module (srt2vtt webvtt) + #:use-module (ice-9 format) + #:use-module (ice-9 match) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:use-module (srt2vtt) + #:export (write-webvtt + write-webvtts)) + +(define (write-time time port) + "Write TIME as a WebVTT formatted timestamp to PORT." + (match time + ((h m s ms) + (format port "~a:~a:~a.~a" h m s ms)))) + +(define (write-webvtt subtitle port) + "Write SUBTITLE as a WebVTT formatted subtitle to PORT." + (format port "~a~%" (subtitle-id subtitle)) + (write-time (subtitle-start subtitle) port) + (display " --> " port) + (write-time (subtitle-end subtitle) port) + (newline port) + (format port "~a~%" (string-join (subtitle-text subtitle) "\n")) + (newline port)) + +(define (write-webvtts subtitles port) + "Write all SUBTITLES as WebVTT formatted subtitles to PORT." + (format port "WEBVTT~%~%") + (for-each (cut write-webvtt <> port) subtitles)) |