[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/subed a97a9e565e 4/5: Add trimming of subtitle overlaps
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/subed a97a9e565e 4/5: Add trimming of subtitle overlaps |
Date: |
Thu, 30 Dec 2021 03:58:47 -0500 (EST) |
branch: elpa/subed
commit a97a9e565ea3ceaacc69db6aef4abe0602fac965
Author: Sacha Chua <sacha@sachachua.com>
Commit: Sacha Chua <sacha@sachachua.com>
Add trimming of subtitle overlaps
You can now trim subtitle overlaps with ~M-x subed-trim-overlaps~. By
default, this adjusts the stop time of overlapping subtitles to
~subed-subtitle-spacing~ milliseconds before the next subtitle
starts. Use ~M-x customize-group~ ~subed~ to configure trimming
to happen automatically when buffers are loaded or saved, which
time is adjusted, and how much time to leave between subtitles.
* README.org (Features): Document M-x subed-trim-overlaps.
* subed/subed-common.el:
(subed-trim-overlaps): New command that trims overlapping subtitles in
the current buffer.
(subed-trim-overlap-stop): New command that adjusts the stop time of
the current subtitle so that it stops before the next subtitle starts.
(subed-trim-overlap-next-start): New command that adjusts the start
time of the next subtitle so that it starts after the current subtitle
stops.
(subed-trim-overlap-check, subed-trim-overlap-maybe-sanitize,
subed-trim-overlap-maybe-check, subed-trim-overlap-stop,
subed--identify-overlaps): New function.
* subed/subed-common.el (subed-sanitize-functions): Add
subed-trim-overlap-maybe-sanitize.
(subed-validate-functions): Add subed-trim-overlap-maybe-check.
* subed/subed-config.el (subed-trim-overlap-on-save,
subed-trim-overlap-check-on-save, subed-trim-overlap-check-on-load,
subed-trim-overlap-use-start): New user options.
Co-authored-by: mooseyboots / mousebot <mousebot@riseup.net>
Based on https://github.com/sachac/subed/pull/50 with some
simplification and reuse.
---
README.org | 6 ++
subed/subed-common.el | 111 ++++++++++++++++++++-
subed/subed-config.el | 36 ++++++-
subed/subed.el | 4 +-
tests/test-subed-common.el | 233 ++++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 385 insertions(+), 5 deletions(-)
diff --git a/README.org b/README.org
index 25ed7bc350..005b762d8c 100644
--- a/README.org
+++ b/README.org
@@ -47,6 +47,12 @@ SubRip ( ~.srt~), WebVTT ( ~.vtt~ ), and Advanced SubStation
Alpha ( ~.ass~, exp
boldface (~C-c C-t C-b~).
- Sort and re-number subtitles and remove any extra spaces and newlines
(~M-s~). This is done automatically every time the buffer is saved.
+ - Trim subtitle overlaps with ~M-x subed-trim-overlaps~. By
+ default, this adjusts the stop time of overlapping subtitles to
+ ~subed-subtitle-spacing~ milliseconds before the next subtitle
+ starts. Use ~M-x customize-group~ ~subed~ to configure trimming
+ to happen automatically when buffers are loaded or saved, which
+ time is adjusted, and how much time to leave between subtitles.
*** mpv integration (optional)
- Open videos with ~C-c C-v~ or automatically when entering subed-mode if
the
diff --git a/subed/subed-common.el b/subed/subed-common.el
index f1640117b1..f6d1891342 100644
--- a/subed/subed-common.el
+++ b/subed/subed-common.el
@@ -1313,13 +1313,120 @@ be run in `after-change-functions'."
'after-string
(propertize (format " %.1f CPS" cps) 'face 'shadow 'display '(height
0.9)))))))
+;;; Trimming overlaps
+
+(defun subed--identify-overlaps ()
+ "Return a list of IDs for subtitles that overlap the next one.
+This observes `subed-subtitle-spacing'."
+ (let (overlap-ids next-sub-start-time)
+ (save-excursion
+ (subed-for-each-subtitle (point-min) (point-max) t
+ (when (and next-sub-start-time
+ (> (+ (subed-subtitle-msecs-stop)
+ subed-subtitle-spacing)
+ next-sub-start-time))
+ (push (subed-subtitle-id) overlap-ids))
+ (setq next-sub-start-time (subed-subtitle-msecs-start)))
+ overlap-ids)))
+
+;; NB: runs in a hook, so this version cannot send prefix arg to
+;; subed-trim-overlaps. Doesn't actually use the whole list of
+;; overlaps, so it may be more efficient to just find the first overlap.
+(defun subed-trim-overlap-check ()
+ "Test all subtitles for overlapping timecodes.
+
+Creates a list of the ids of overlapping subtitles, moves point
+to the end time of the first one, and prompts to trim
+them. Designed to be run in `subed-mode-hook'."
+ (interactive)
+ (let ((overlap-ids (subed--identify-overlaps)))
+ (when overlap-ids
+ (subed-jump-to-subtitle-time-stop (car overlap-ids))
+ (when (yes-or-no-p "Overlapping subtitles found. Trim them? ")
+ (subed-trim-overlaps)))))
+
+(defun subed-trim-overlaps (&optional msecs)
+ "Adjust all overlapping times in current file.
+
+Change the stop times to start MSECS before the next subtitle, or
+`subed-subtitle-spacing' if not specified. If
+`subed-trim-overlap-use-start' is non-nil, change
+the start times instead."
+ (interactive "P")
+ (subed-batch-edit
+ (save-excursion
+ (subed-for-each-subtitle (point-min) (point-max) nil
+ (if subed-trim-overlap-use-start
+ (subed-trim-overlap-next-start msecs)
+ (subed-trim-overlap-stop msecs))))))
+
+(defun subed-trim-overlap-maybe-sanitize ()
+ "Trim overlaps if specified by `subed-trim-overlap-on-save'."
+ (when subed-trim-overlap-on-save
+ (subed-trim-overlaps)))
+
+(defun subed-trim-overlap-maybe-check ()
+ "Check overlaps if specified by `subed-trim-overlap-check-on-save'."
+ (when subed-trim-overlap-check-on-save
+ (subed-trim-overlap-check)))
+
+(defun subed-trim-overlap-stop (&optional msecs ignore-negative-duration)
+ "Trim the current subtitle so that it stops before the next one.
+
+Trim the end time of the current subtitle to MSECS or
+`subed-subtitle-spacing' less than the start time of the next
+subtitle. Unless either IGNORE-NEGATIVE-DURATION or
+`subed-enforce-time-boundaries' are non-nil, adjust MSECS so that
+the stop time isn't smaller than the start time."
+ (interactive "P")
+ (let ((next-sub-start-time (save-excursion
+ (and
+ (subed-forward-subtitle-time-start)
+ (subed-subtitle-msecs-start))))
+ (this-sub-stop-time (subed-subtitle-msecs-stop)))
+ (when (and next-sub-start-time this-sub-stop-time)
+ (subed-adjust-subtitle-time-stop
+ (min 0
+ (- (- next-sub-start-time
+ (if (numberp msecs) msecs subed-subtitle-spacing))
+ this-sub-stop-time))
+ ignore-negative-duration
+ t))))
+
+(defun subed-trim-overlap-next-start (&optional msecs ignore-negative-duration)
+ "Trim the next subtitle so that it starts after the current one.
+
+Trim the start time of the next subtitle to MSECS or
+`subed-subtitle-spacing' greater than the end time of the current
+subtitle. Unless either IGNORE-NEGATIVE-DURATION or
+`subed-enforce-time-boundaries' are non-nil, adjust MSECS so that
+the stop time isn't smaller than the start time."
+ (interactive "P")
+ (save-excursion
+ (let ((this-sub-stop-time (subed-subtitle-msecs-stop))
+ (next-sub-start-time (and
+ (subed-forward-subtitle-time-start)
+ (subed-subtitle-msecs-start))))
+ (when (and this-sub-stop-time
+ next-sub-start-time
+ (or msecs subed-subtitle-spacing))
+ (subed-adjust-subtitle-time-start
+ (max 0
+ (-
+ (+ this-sub-stop-time (or msecs subed-subtitle-spacing))
+ next-sub-start-time))
+ ignore-negative-duration
+ t)))))
+
;;; Sorting and sanitizing
-(defvar-local subed-sanitize-functions nil
+(defvar-local subed-sanitize-functions
+ '(subed-trim-overlap-maybe-sanitize)
"Functions to sanitize this buffer.
Functions can clean up whitespace, rearrange subtitles, etc.")
-(defvar-local subed-validate-functions nil
+(defvar-local subed-validate-functions
+ '(subed-trim-overlap-maybe-check)
"Functions to validate this buffer.
Validation functions should throw an error or prompt the user for
action.")
diff --git a/subed/subed-config.el b/subed/subed-config.el
index de5d221658..8c584c739b 100644
--- a/subed/subed-config.el
+++ b/subed/subed-config.el
@@ -210,8 +210,42 @@ hardcoded."
"Return base name of buffer file name or a default name."
(file-name-nondirectory (or (buffer-file-name) "unnamed")))
+;;; Trim overlaps
+
+;; checked by subed-sort
+(defcustom subed-trim-overlap-on-save nil
+ "Non-nil means trim all overlapping subtitles when saving.
+Subtitles are trimmed according to `subed-trim-overlap-use-start'."
+ :type '(choice
+ (const :tag "Trim" nil)
+ (const :tag "Do not trim" t))
+ :group 'subed)
+
+(defcustom subed-trim-overlap-check-on-save nil
+ "Non-nil means check for overlapping subtitles when saving."
+ :type '(choice
+ (const :tag "Check" nil)
+ (const :tag "Do not check" t))
+ :group 'subed)
+
+;; checked by subed mode hook
+(defcustom subed-trim-overlap-check-on-load nil
+ "Non-nil means check for overlapping subtitles on entering subed mode.
+Subtitles are trimmed according to `subed-trim-overlap-use-start'."
+ :type '(choice
+ (const :tag "Check" t)
+ (const :tag "Do not check" nil))
+ :group 'subed)
+
+(defcustom subed-trim-overlap-use-start nil
+ "Non-nil means adjust the start time of the following subtitle for overlaps.
+Otherwise, adjust the stop time of the current subtitle."
+ :type '(choice
+ (const :tag "Adjust stop time of the current subtitle" nil)
+ (const :tag "Adjust start time of the next subtitle" t))
+ :group 'subed)
-;; Hooks
+;;; Hooks
(defvar-local subed-subtitle-time-adjusted-hook ()
"Functions to call when a subtitle's start or stop time has changed.
diff --git a/subed/subed.el b/subed/subed.el
index 119c4249c2..3366d08fbc 100644
--- a/subed/subed.el
+++ b/subed/subed.el
@@ -1,6 +1,6 @@
;;; subed.el --- A major mode for editing subtitles -*- lexical-binding: t;
-*-
-;; Version: 0.0.2
+;; Version: 0.0.3
;; Keywords: convenience, files, hypermedia, multimedia
;; URL: https://github.com/rndusr/subed
;; Package-Requires: ((emacs "25.1"))
@@ -197,6 +197,8 @@ Key bindings:
(add-hook 'after-save-hook #'subed-mpv-reload-subtitles :append :local)
(add-hook 'kill-buffer-hook #'subed-mpv-kill :append :local)
(add-hook 'kill-emacs-hook #'subed-mpv-kill :append :local)
+ (when subed-trim-overlap-check-on-load
+ (add-hook 'subed-mode-hook #'subed-trim-overlap-check :append :local))
(when subed-auto-find-video
(let ((video-file (subed-guess-video-file)))
(when video-file
diff --git a/tests/test-subed-common.el b/tests/test-subed-common.el
index f0f14909fd..83fcb168e4 100644
--- a/tests/test-subed-common.el
+++ b/tests/test-subed-common.el
@@ -2323,7 +2323,6 @@ This is another.
(setq-local subed-mpv-playback-position 61600)
(setq-local subed-subtitle-spacing 100)
(subed-split-subtitle)
- (prin1 (buffer-string))
(expect (subed-subtitle-msecs-start) :to-equal 61700)
(expect (subed-subtitle-msecs-stop) :to-equal 65123)
(expect (subed-subtitle-text) :to-equal "Some text here.")
@@ -2866,3 +2865,235 @@ This is another.
(expect (subed-scale-subtitles 1000 5 4) :to-throw 'error)
(expect (spy-calls-all-args 'user-error) :to-equal
'(("Can't scale with improper range"))))))
+
+(describe "Trimming subtitles"
+ (describe "when spacing is 0"
+ (it "detects overlaps"
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:05,000\nA\n\n"
+ "2\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 0))
+ (expect (subed--identify-overlaps)
+ :to-equal '(1)))))
+ (it "ignores non-overlapping subtitles"
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,000\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 0))
+ (expect (subed--identify-overlaps)
+ :to-equal nil)))))
+ (describe "when spacing is 1"
+ (it "detects overlaps"
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:04,000\nA\n\n"
+ "2\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 1))
+ (expect (subed--identify-overlaps)
+ :to-equal '(1)))))
+ (it "ignores non-overlapping subtitles"
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,999\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,000\nA\n\n")
+ (let ((subed-subtitle-spacing 1))
+ (expect (subed--identify-overlaps)
+ :to-equal nil)))))
+ (describe "when spacing is greater"
+ (it "detects overlaps because of spacing"
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,999\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:05,000\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (expect (subed--identify-overlaps)
+ :to-equal '(1 2)))))
+ (it "ignores non-overlapping subtitles."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:03,500\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (expect (subed--identify-overlaps)
+ :to-equal nil)))))
+ (describe "overlap end time"
+ (it "sets it to the next timestamp minus spacing."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (subed-jump-to-subtitle-id 2)
+ (subed-trim-overlap-stop)
+ (expect (subed-subtitle-msecs-stop) :to-equal 3900))))
+ (it "sets it to the next timestamp minus the argument."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (subed-jump-to-subtitle-id 2)
+ (subed-trim-overlap-stop 500)
+ (expect (subed-subtitle-msecs-stop) :to-equal 3500))))
+ (it "ignores non-overlapping subtitles."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (subed-jump-to-subtitle-id 1)
+ (subed-trim-overlap-stop)
+ (expect (subed-subtitle-msecs-stop) :to-equal 2000))))
+ (it "handles the last subtitle gracefully."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (subed-jump-to-subtitle-id 3)
+ (subed-trim-overlap-stop 500)
+ (expect (subed-subtitle-msecs-stop) :to-equal 6000))))
+ (it "handles empty buffers gracefully."
+ (with-temp-srt-buffer
+ (subed-trim-overlap-stop 500)
+ (expect (subed-subtitle-msecs-stop) :to-equal nil)))
+ (it "adjusts the stop time if the new stop would be before the start time."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,500 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (subed-jump-to-subtitle-id 1)
+ (expect (subed-trim-overlap-stop) :to-equal -500)
+ (expect (subed-subtitle-msecs-stop 1) :to-equal 1500)
+ (expect (subed-subtitle-msecs-start 1) :to-equal 1500)))))
+ (describe "overlap start time"
+ (it "sets next start to the current timestamp plus spacing."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (subed-jump-to-subtitle-id 2)
+ (subed-trim-overlap-next-start)
+ (subed-forward-subtitle-time-start)
+ (expect (subed-subtitle-msecs-start) :to-equal 4600))))
+ (it "sets next start to the current timestamp plus the argument."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (subed-jump-to-subtitle-id 2)
+ (subed-trim-overlap-next-start 500)
+ (subed-forward-subtitle-time-start)
+ (expect (subed-subtitle-msecs-start) :to-equal 5000))))
+ (it "handles the last subtitle gracefully."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (subed-jump-to-subtitle-id 3)
+ (subed-trim-overlap-next-start 500)
+ (expect (subed-subtitle-msecs-start) :to-equal 4000))))
+ (it "adjusts the timestamp if the new start is past the stop time."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:01,500 --> 00:00:02,000\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (subed-jump-to-subtitle-id 1)
+ (expect (subed-trim-overlap-next-start 500) :to-equal 500)
+ (expect (subed-subtitle-msecs-start 2) :to-equal 2000))))
+ (it "handles empty buffers gracefully."
+ (with-temp-srt-buffer
+ (subed-trim-overlap-next-start 500)
+ (expect (subed-subtitle-msecs-stop) :to-equal nil))))
+ (describe "trimming overlaps"
+ (it "adjusts stop times by default."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n"
+ "4\n00:00:05,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (subed-trim-overlaps))
+ (expect (subed-subtitle-msecs-stop 1) :to-equal 2000)
+ (expect (subed-subtitle-msecs-stop 2) :to-equal 3900)
+ (expect (subed-subtitle-msecs-stop 3) :to-equal 4900)))
+ (it "adjusts start times if specified."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n"
+ "4\n00:00:05,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100)
+ (subed-trim-overlap-use-start t))
+ (subed-trim-overlaps)
+ (expect (subed-subtitle-msecs-stop 1) :to-equal 2000)
+ (expect (subed-subtitle-msecs-stop 2) :to-equal 4500)
+ (expect (subed-subtitle-msecs-start 3) :to-equal 4600)
+ (expect (subed-subtitle-msecs-start 4) :to-equal 6000))))
+ (it "can specify the number of milliseconds."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "3\n00:00:04,000 --> 00:00:06,000\nA\n\n"
+ "4\n00:00:05,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (subed-trim-overlaps 200))
+ (expect (subed-subtitle-msecs-stop 1) :to-equal 2000)
+ (expect (subed-subtitle-msecs-stop 2) :to-equal 3800)
+ (expect (subed-subtitle-msecs-stop 3) :to-equal 4800)))
+ (it "handles empty buffers gracefully."
+ (with-temp-srt-buffer
+ (expect (subed-trim-overlaps) :not :to-throw)))
+ (it "handles single subtitles gracefully."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n")
+ (let ((subed-subtitle-spacing 100))
+ (expect (subed-trim-overlaps) :not :to-throw))
+ (expect (subed-subtitle-msecs-start 1) :to-equal 1000)
+ (expect (subed-subtitle-msecs-stop 1) :to-equal 2000))))
+ (describe "when configured to trim on save,"
+ (it "trims overlaps after sorting."
+ (with-temp-srt-buffer
+ (let ((subed-trim-overlap-on-save t)
+ (subed-subtitle-spacing 200))
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:04,000 --> 00:00:06,000\nA\n\n"
+ "3\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "4\n00:00:05,000 --> 00:00:06,000\nA\n\n")
+ (subed-prepare-to-save)
+ (expect (subed-subtitle-msecs-stop 1) :to-equal 2000)
+ (expect (subed-subtitle-msecs-stop 2) :to-equal 3800)
+ (expect (subed-subtitle-msecs-stop 3) :to-equal 4800)))))
+ (describe "when configured to check on save,"
+ (it "reports overlaps after sorting."
+ (with-temp-srt-buffer
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:04,000 --> 00:00:06,000\nA\n\n"
+ "3\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "4\n00:00:05,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-trim-overlap-check-on-save t)
+ (subed-subtitle-spacing 200))
+ (spy-on 'yes-or-no-p :and-return-value t)
+ (subed-prepare-to-save)
+ (expect 'yes-or-no-p :to-have-been-called)
+ (expect (subed-subtitle-msecs-stop 1) :to-equal 2000)
+ (expect (subed-subtitle-msecs-stop 2) :to-equal 3800)
+ (expect (subed-subtitle-msecs-stop 3) :to-equal 4800)))))
+ (describe "when configured to check on load,"
+ (it "reports overlaps."
+ (with-temp-buffer
+ (setq buffer-file-name "test.srt")
+ (insert "1\n00:00:01,000 --> 00:00:02,000\nA\n\n"
+ "2\n00:00:04,000 --> 00:00:06,000\nA\n\n"
+ "3\n00:00:03,000 --> 00:00:04,500\nA\n\n"
+ "4\n00:00:05,000 --> 00:00:06,000\nA\n\n")
+ (let ((subed-trim-overlap-check-on-load t)
+ (subed-subtitle-spacing 200))
+ (spy-on 'subed-trim-overlap-check :and-return-value nil)
+ (subed-mode)
+ (expect subed--subtitle-format :to-equal "srt")
+ (expect 'subed-trim-overlap-check :to-have-been-called))))))