branch: elpa/subed
commit 49ced737ad979ccd5a06edefa9c5867eae4fdc41
Author: Sacha Chua <[email protected]>
Commit: Sacha Chua <[email protected]>
VTT: New commands for working with subtitle comments
* subed/subed-vtt.el (subed-vtt-copy-subtitle-comments): New command.
(subed-vtt-select-section-between-comments): New command.
(subed-vtt-group-subtitles-by-chapter): New function.
(subed-vtt-move-comment-to-previous-subtitle): New command.
(subed-vtt-move-comment-to-next-subtitle): New command.
* tests/test-subed-vtt.el ("subed-vtt"): Test grouping subtitles
---
subed/subed-vtt.el | 69 +++++++++++++++++++++++++++++++++++++++++++++++++
tests/test-subed-vtt.el | 23 +++++++++++++++++
2 files changed, 92 insertions(+)
diff --git a/subed/subed-vtt.el b/subed/subed-vtt.el
index b0b4198a13..8f13d6af48 100644
--- a/subed/subed-vtt.el
+++ b/subed/subed-vtt.el
@@ -724,6 +724,21 @@ This uses clock time based on `subed-clock-start'."
(subed-set-subtitle-comment text)))
(pop chapter-list)))))
+;;;###autoload
+(defun subed-vtt-copy-subtitle-comments (file)
+ "Copy subtitle comments from FILE.
+Match subtitles based on time."
+ (interactive "FFile to copy from: ")
+ (let ((cues-with-comments
+ (seq-filter (lambda (o) (elt o 4))
+ (subed-parse-file file))))
+ (subed-for-each-subtitle (point-min) (point-max) nil
+ (when (and cues-with-comments
+ (>= (subed-subtitle-msecs-stop)
+ (elt (car cues-with-comments) 1)))
+ (subed-set-subtitle-comment (elt (car cues-with-comments) 4))
+ (pop cues-with-comments)))))
+
;;;###autoload
(defun subed-vtt-mpv-skim-subtitles-with-comments (&optional msecs)
"Play the first MSECS of each subtitle with a comment from point to end of
buffer.
@@ -759,6 +774,60 @@ If MSECS is not specified, use `subed-mpv-skim-msecs'."
(re-search-backward regexp nil t))
(subed-mpv-pause))
+(defun subed-vtt-select-section-between-comments ()
+ "Select the subtitles between NOTE comments."
+ (interactive)
+ (save-excursion
+ (or (re-search-backward "^NOTE" nil t)
+ (goto-char (point-min)))
+ (push-mark (point)))
+ (if (re-search-forward "^NOTE" nil t)
+ (goto-char (match-beginning 0))
+ (goto-char (point-max)))
+ (activate-mark))
+
+(defun subed-vtt-group-subtitles-by-chapter (&optional subtitles)
+ "Group SUBTITLES by comments."
+ (let* ((subtitles (or subtitles (subed-subtitle-list)))
+ result)
+ (dolist (o subtitles)
+ (let ((chapter
+ (and (elt o 4)
+ (elt (car
+ (seq-reduce
+ (lambda (prev val)
+ (funcall val prev))
+ subed-section-comments-as-chapters-functions
+ (list (copy-sequence o))))
+ 4))))
+ (if (or chapter (null result))
+ (push
+ (cons (and chapter (string-trim chapter))
+ (list o))
+ result)
+ (push o (cdr (car result))))))
+ (mapcar (lambda (o) (cons (car o)
+ (nreverse (cdr o))))
+ (nreverse result))))
+
+;;;###autoload
+(defun subed-vtt-move-comment-to-previous-subtitle ()
+ "Move the comment for this subtitle to the previous one."
+ (interactive)
+ (let ((comment (subed-subtitle-comment)))
+ (subed-set-subtitle-comment nil)
+ (subed-backward-subtitle-text)
+ (subed-set-subtitle-comment comment)))
+
+;;;###autoload
+(defun subed-vtt-move-comment-to-next-subtitle ()
+ "Move the comment for this subtitle to the next one."
+ (interactive)
+ (let ((comment (subed-subtitle-comment)))
+ (subed-set-subtitle-comment nil)
+ (subed-forward-subtitle-text)
+ (subed-set-subtitle-comment comment)))
+
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.vtt\\'" . subed-vtt-mode))
diff --git a/tests/test-subed-vtt.el b/tests/test-subed-vtt.el
index 43867d1370..48834015b9 100644
--- a/tests/test-subed-vtt.el
+++ b/tests/test-subed-vtt.el
@@ -2834,6 +2834,29 @@ NOTE Part 2
00:30:00.000 --> 00:35:00.000
Subtitle D.
")))))
+ (describe "grouping subtitles by chapters"
+ :var (chapters)
+ (before-all
+ (setq chapters
+ (with-temp-vtt-buffer
+ (subed-append-subtitle-list
+ '((nil 1000 2000 "Cue 1.")
+ (nil 3000 4000 "Cue 2.")
+ (nil 4000 5000 "Cue 3." "Chapter Title A")
+ (nil 6000 7000 "Cue 4.")
+ (nil 8000 9000 "Cue 5." "Chapter Title B\n#+SCREENSHOT:
test.jpg")
+ (nil 4000 5000 "Cue 6." "Chapter Title A")))
+ (subed-vtt-group-subtitles-by-chapter))))
+ (it "includes subtitles before the first chapter."
+ (expect (car (car chapters)) :to-be nil)
+ (expect (elt (elt (cdr (car chapters)) 0) 3) :to-equal "Cue 1.")
+ (expect (elt (elt (cdr (car chapters)) 1) 3) :to-equal "Cue 2."))
+ (it "does not reuse chapters."
+ (expect (length chapters) :to-equal 4)
+ (expect (car (car (last chapters))) :to-equal "Chapter Title A"))
+ (it "preserves other parts of the comment."
+ (expect (elt (cadr (elt chapters 3))) :to-equal "Chapter Title
B\n#+SCREENSHOT: test.jpg")
+ ))
(it "can replace [speaker-name]: with <v speaker-name>..</v>."
(with-temp-vtt-buffer
(subed-append-subtitle-list