branch: elpa/subed commit 08e97626d086de88bc12265c2b4a9c5518d11b3c Author: Random User <rnd...@posteo.de> Commit: Random User <rnd...@posteo.de>
Add option to ignore negative duration when adjusting start/stop time --- subed/subed-srt.el | 86 ++++++++++++++++++++++++++++------------------- tests/test-subed-srt.el | 88 +++++++++++++++++++++++++++++++------------------ 2 files changed, 108 insertions(+), 66 deletions(-) diff --git a/subed/subed-srt.el b/subed/subed-srt.el index c87772d..b9456c9 100644 --- a/subed/subed-srt.el +++ b/subed/subed-srt.el @@ -315,29 +315,39 @@ Return point or nil if there is no previous subtitle." ;;; Manipulation -(defun subed-srt--adjust-subtitle-start (msecs &optional ignore-spacing) +(defun subed-srt--adjust-subtitle-start (msecs &optional + ignore-negative-duration + ignore-spacing) "Add MSECS milliseconds to start time (use negative value to subtract). -If the adjustment would result in overlapping subtitles, reduce -MSECS so that there are at least `subed-subtitle-spacing' -milliseconds between subtitles. If IGNORE-SPACING is non-nil -this limitation is disabled. +Unless IGNORE-NEGATIVE-DURATION is non-nil, recude MSECS so that +the start time isn't larger than the stop time. Zero-length +subtiltes are always allowed. + +Unless IGNORE-SPACING is non-nil, if the adjustment would result +in gaps between subtitles being smaller than +`subed-subtitle-spacing', reduce MSECS so that this doesn't +happen. Return the number of milliseconds the start time was adjusted or -nil if nothing was adjusted." +nil if nothing changed." (subed-disable-sync-point-to-player-temporarily) (let* ((msecs-start (subed-srt--subtitle-msecs-start)) - (msecs-new (when msecs-start (+ msecs-start msecs))) - (msecs-prev (save-excursion - (when (subed-srt--backward-subtitle-id) - (subed-srt--subtitle-msecs-stop)))) - (msecs-min (if ignore-spacing nil (if msecs-prev (+ msecs-prev subed-subtitle-spacing) 0))) - (msecs-max (if ignore-spacing nil (subed-srt--subtitle-msecs-stop)))) + (msecs-new (when msecs-start (+ msecs-start msecs)))) (when msecs-new - (when (and msecs-min (< msecs-new msecs-min)) - (setq msecs-new msecs-min)) - (when (and msecs-max (> msecs-new msecs-max)) - (setq msecs-new msecs-max)) + (if (> msecs 0) + ;; Adding to start time + (unless ignore-negative-duration + (let ((msecs-stop (subed-srt--subtitle-msecs-stop))) + (setq msecs-new (min msecs-new msecs-stop)))) + ;; Subtracting from start time + (unless ignore-spacing + (let* ((msecs-prev-stop (save-excursion (when (subed-srt--backward-subtitle-id) + (subed-srt--subtitle-msecs-stop)))) + (msecs-min (if msecs-prev-stop + (+ msecs-prev-stop subed-subtitle-spacing) 0))) + (when msecs-min + (setq msecs-new (max msecs-new msecs-min)))))) ;; msecs-new must be bigger than the current start time if we are adding ;; or smaller if we are subtracting. (when (or (and (> msecs 0) (> msecs-new msecs-start)) ;; Adding @@ -349,31 +359,39 @@ nil if nothing was adjusted." (subed--run-subtitle-time-adjusted-hook) (- msecs-new msecs-start))))))) -(defun subed-srt--adjust-subtitle-stop (msecs &optional ignore-spacing) +(defun subed-srt--adjust-subtitle-stop (msecs &optional + ignore-negative-duration + ignore-spacing) "Add MSECS milliseconds to stop time (use negative value to subtract). -If the adjustment would result in overlapping subtitles, reduce -MSECS so that there are at least `subed-subtitle-spacing' -milliseconds between subtitles. If IGNORE-SPACING is non-nil -this limitation is disabled. +Unless IGNORE-NEGATIVE-DURATION is non-nil, increase MSECS so +that the stop time isn't smaller than the start time. +Zero-length subtiltes are always allowed. + +Unless IGNORE-SPACING is non-nil, if the adjustment would result +in gaps between subtitles being smaller than +`subed-subtitle-spacing', reduce MSECS so that this doesn't +happen. Return the number of milliseconds the stop time was adjusted or -nil if nothing was adjusted." +nil if nothing changed." (subed-disable-sync-point-to-player-temporarily) (let* ((msecs-stop (subed-srt--subtitle-msecs-stop)) - (msecs-new (when msecs-stop (+ msecs-stop msecs))) - (msecs-next (save-excursion - (when (subed-srt--forward-subtitle-id) - (subed-srt--subtitle-msecs-start)))) - (msecs-min (if ignore-spacing nil (subed-srt--subtitle-msecs-start))) - (msecs-max (if ignore-spacing nil (when msecs-next - (- msecs-next subed-subtitle-spacing))))) - (message "min:%S max:%S" msecs-min msecs-max) + (msecs-new (when msecs-stop (+ msecs-stop msecs)))) (when msecs-new - (when (and msecs-min (< msecs-new msecs-min)) - (setq msecs-new msecs-min)) - (when (and msecs-max (> msecs-new msecs-max)) - (setq msecs-new msecs-max)) + (if (> msecs 0) + ;; Adding to stop time + (unless ignore-spacing + (let* ((msecs-next-start (save-excursion (when (subed-srt--forward-subtitle-id) + (subed-srt--subtitle-msecs-start)))) + (msecs-max (when msecs-next-start + (- msecs-next-start subed-subtitle-spacing)))) + (when msecs-max + (setq msecs-new (min msecs-new msecs-max))))) + ;; Subtracting from stop time + (unless ignore-negative-duration + (let ((msecs-start (subed-srt--subtitle-msecs-start))) + (setq msecs-new (max msecs-new msecs-start))))) ;; msecs-new must be bigger than the current stop time if we are adding or ;; smaller if we are subtracting. (when (or (and (> msecs 0) (> msecs-new msecs-stop)) ;; Adding diff --git a/tests/test-subed-srt.el b/tests/test-subed-srt.el index 08106d8..0475476 100644 --- a/tests/test-subed-srt.el +++ b/tests/test-subed-srt.el @@ -655,38 +655,6 @@ Baz. (expect (save-excursion (subed-srt--jump-to-subtitle-time-stop) (thing-at-point 'line)) :to-equal "00:03:03,550 --> 00:03:15,400\n"))) (describe "enforces limits" - (describe "unless the second argument is truthy" - (it "when adjusting start time." - (with-temp-buffer - (insert (concat "1\n" - "00:00:01,000 --> 00:00:02,000\n" - "Foo.\n\n" - "2\n" - "00:00:02,100 --> 00:00:03,000\n" - "Bar.\n")) - (subed-srt--jump-to-subtitle-id 2) - (expect (subed-srt--adjust-subtitle-start -100 :ignore-spacing) :to-be -100) - (expect (subed-srt--subtitle-msecs-start 2) :to-be 2000) - (expect (subed-srt--subtitle-msecs-stop 1) :to-be 2000) - (expect (subed-srt--adjust-subtitle-start -200 :ignore-spacing) :to-be -200) - (expect (subed-srt--subtitle-msecs-start 2) :to-be 1800) - (expect (subed-srt--subtitle-msecs-stop 1) :to-be 2000))) - (it "when adjusting stop time." - (with-temp-buffer - (insert (concat "1\n" - "00:00:01,000 --> 00:00:02,000\n" - "Foo.\n\n" - "2\n" - "00:00:02,100 --> 00:00:03,000\n" - "Bar.\n")) - (subed-srt--jump-to-subtitle-id 1) - (expect (subed-srt--adjust-subtitle-stop 100 :ignore-spacing) :to-be 100) - (expect (subed-srt--subtitle-msecs-stop 1) :to-be 2100) - (expect (subed-srt--subtitle-msecs-start 2) :to-be 2100) - (expect (subed-srt--adjust-subtitle-stop 200 :ignore-spacing) :to-be 200) - (expect (subed-srt--subtitle-msecs-stop 1) :to-be 2300) - (expect (subed-srt--subtitle-msecs-start 2) :to-be 2100))) - ) (describe "when decreasing start time" (it "of the first subtitle." (with-temp-buffer @@ -797,6 +765,62 @@ Baz. (expect (subed-srt--adjust-subtitle-start -1) :to-be nil) (expect (subed-subtitle-msecs-start) :to-equal 2000))) ) + (describe "ignores negative duration if the first argument is truthy" + (it "when adjusting start time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n")) + (expect (subed-srt--adjust-subtitle-start 2000 t) :to-be 2000) + (expect (subed-srt--subtitle-msecs-start) :to-be 3000) + (expect (subed-srt--subtitle-msecs-stop) :to-be 2000) + (expect (subed-srt--adjust-subtitle-start -500 t) :to-be -500) + (expect (subed-srt--subtitle-msecs-start) :to-be 2500) + (expect (subed-srt--subtitle-msecs-stop) :to-be 2000))) + (it "when adjusting stop time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n")) + (expect (subed-srt--adjust-subtitle-stop -1500 t) :to-be -1500) + (expect (subed-srt--subtitle-msecs-stop) :to-be 500) + (expect (subed-srt--subtitle-msecs-start) :to-be 1000) + (expect (subed-srt--adjust-subtitle-stop 200 t) :to-be 200) + (expect (subed-srt--subtitle-msecs-stop) :to-be 700) + (expect (subed-srt--subtitle-msecs-start) :to-be 1000))) + ) + (describe "ignores subtitle spacing if the second argument is truthy" + (it "when adjusting start time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "2\n" + "00:00:02,200 --> 00:00:03,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-id 2) + (expect (subed-srt--adjust-subtitle-start -150 nil t) :to-be -150) + (expect (subed-srt--subtitle-msecs-start 2) :to-be 2050) + (expect (subed-srt--subtitle-msecs-stop 1) :to-be 2000) + (expect (subed-srt--adjust-subtitle-start -51 nil t) :to-be -51) + (expect (subed-srt--subtitle-msecs-start 2) :to-be 1999) + (expect (subed-srt--subtitle-msecs-stop 1) :to-be 2000))) + (it "when adjusting stop time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "2\n" + "00:00:02,200 --> 00:00:03,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-id 1) + (expect (subed-srt--adjust-subtitle-stop 150 nil t) :to-be 150) + (expect (subed-srt--subtitle-msecs-stop 1) :to-be 2150) + (expect (subed-srt--subtitle-msecs-start 2) :to-be 2200) + (expect (subed-srt--adjust-subtitle-stop 51 nil t) :to-be 51) + (expect (subed-srt--subtitle-msecs-stop 1) :to-be 2201) + (expect (subed-srt--subtitle-msecs-start 2) :to-be 2200))) + ) (it "does nothing if no timestamp can be found." (with-temp-buffer (insert "foo")