emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/subed b6e484f 204/389: Move subtitles in active region as


From: ELPA Syncer
Subject: [nongnu] elpa/subed b6e484f 204/389: Move subtitles in active region as a unit
Date: Fri, 3 Dec 2021 11:00:26 -0500 (EST)

branch: elpa/subed
commit b6e484f615c317ee72199fe72d1c4cbf3d2a9874
Author: Random User <rndusr@posteo.de>
Commit: Random User <rndusr@posteo.de>

    Move subtitles in active region as a unit
    
    Usually, it's illegal to make the start time larger than the stop time or to
    make the stop time larger than the next subtitle's start time.  But if we 
move
    subtitles in a region, we expect their time stamps not to change relatively 
to
    each other.  That means we must allow negative durations and negative 
subtitle
    spacing when moving the active region.
    
    But we only allow it in the active region.  We don't want the leading
    subtitle (i.e. the last subtitle in the active region when moving forward 
and
    the first subtitle in the active region when moving backward) to be able to
    overlap with it's neighbour.  So we move the leading subtitle first, 
applying
    all the usual limitations, and check how far it actually moved.  Then we can
    move the rest of the subtitles by the same amount.
---
 subed/subed.el | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 73 insertions(+), 11 deletions(-)

diff --git a/subed/subed.el b/subed/subed.el
index 9585e83..8c8c8e1 100644
--- a/subed/subed.el
+++ b/subed/subed.el
@@ -255,9 +255,79 @@ See `subed-increase-start-time' about ARG."
     (replace-match (subed-srt--msecs-to-timestamp subed-mpv-playback-position))
     (subed--run-subtitle-time-adjusted-hook)))
 
+
 ;;; Moving subtitles
 ;;; (adjusting start and stop time by the same amount)
 
+(defun subed--get-move-subtitle-func (msecs)
+  "Return subtitle moving function.
+
+When moving subtitles forward (MSECS > 0), we must adjust the
+stop time first and adjust the start time by the same amount the
+stop time was adjusted.  This ensures that subtitle length
+doesn't change if we can't move MSECS milliseconds forward
+because we'd overlap with the next subtitle.
+
+When moving subtitles backward (MSECS < 0), it's the same thing
+but we move the start time first."
+  (if (> msecs 0)
+      (lambda (msecs &optional ignore-limits)
+        (let ((msecs (subed-adjust-subtitle-stop msecs
+                                                 :ignore-negative-duration
+                                                 ignore-limits)))
+          (when msecs (subed-adjust-subtitle-start msecs
+                                                   :ignore-negative-duration
+                                                   ignore-limits))))
+  (lambda (msecs &optional ignore-limits)
+    (let ((msecs (subed-adjust-subtitle-start msecs
+                                              :ignore-negative-duration
+                                              ignore-limits)))
+      (when msecs (subed-adjust-subtitle-stop msecs
+                                              :ignore-negative-duration
+                                              ignore-limits))))))
+
+(defun subed--move-current-subtitle (msecs)
+  "Move subtitle on point by MSECS milliseconds."
+  (unless (= msecs 0)
+    (subed-with-subtitle-replay-disabled
+      (cl-flet ((move-subtitle (subed--get-move-subtitle-func msecs)))
+        (move-subtitle msecs)))))
+
+(defun subed--move-subtitles-in-region (msecs beg end)
+  "Move subtitles in region specified by BEG and END by MSECS milliseconds."
+  (unless (= msecs 0)
+    (subed-with-subtitle-replay-disabled
+      (cl-flet ((move-subtitle (subed--get-move-subtitle-func msecs)))
+        ;; When moving subtitles forward, the first step is to move the last
+        ;; subtitle because:
+        ;;     a) We need to check if we can move at all and abort if not.
+        ;;     b) We may have to reduce MSECS if we can move but not by the 
full
+        ;;        amount. The goal is that all subtitles are moved by the same
+        ;;        amount and the spacing between subtitles doesn't change.
+        ;; All other subtitles must be moved without any checks because we only
+        ;; ensure that the active region as a whole can be moved, not it's
+        ;; individual parts, which may be too close together or even overlap.
+        ;; Moving subtitles backward is basically the same thing but vice 
versa.
+        (catch 'bumped-into-subtitle
+          (if (> msecs 0)
+              (save-excursion
+                ;; Moving forward - Start on last subtitle to see if/how far
+                ;; we can move forward.
+                (goto-char end)
+                (unless (setq msecs (move-subtitle msecs))
+                  (throw 'bumped-into-subtitle t))
+                (subed-backward-subtitle-id)
+                (subed-for-each-subtitle beg (point) :reverse
+                  (move-subtitle msecs :ignore-spacing)))
+            ;; Start on first subtitle to see if/how far we can move backward.
+            (save-excursion
+              (goto-char beg)
+              (unless (setq msecs (move-subtitle msecs))
+                (throw 'bumped-into-subtitle t))
+              (subed-forward-subtitle-id)
+              (subed-for-each-subtitle (point) end
+                (move-subtitle msecs :ignore-spacing)))))))))
+
 (defun subed-move-subtitles (msecs &optional beg end)
   "Move subtitles between BEG and END MSECS milliseconds forward.
 Use a negative MSECS value to move subtitles backward.
@@ -265,17 +335,9 @@ If END is nil, move all subtitles from BEG to end of 
buffer.
 If BEG is nil, move only the current subtitle.
 After subtitles are moved, replay the first moved subtitle if
 replaying is enabled."
-  (subed-with-subtitle-replay-disabled
-    (subed-for-each-subtitle beg end
-      (if (> msecs 0)
-          ;; Moving subtitles forward may reduce MSECS if there isn't enough
-          ;; room for the full movement.  Using the MSECS the stop time was
-          ;; moved to move the start time ensures that subtitle length doesn't
-          ;; change.
-          (let ((msecs (subed-adjust-subtitle-stop msecs)))
-            (when msecs (subed-adjust-subtitle-start msecs)))
-        (let ((msecs (subed-adjust-subtitle-start msecs)))
-          (when msecs (subed-adjust-subtitle-stop msecs))))))
+  (cond ((and beg end) (subed--move-subtitles-in-region msecs beg end))
+        (beg (subed--move-subtitles-in-region msecs beg (point-max)))
+        (t (subed--move-current-subtitle msecs)))
   (when (subed-replay-adjusted-subtitle-p)
     (save-excursion
       (when beg (goto-char beg))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]