[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))
- [nongnu] elpa/subed 34caefb 117/389: Explain usage of prefix argument when adjusting/moving, (continued)
- [nongnu] elpa/subed 34caefb 117/389: Explain usage of prefix argument when adjusting/moving, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed b1cb470 134/389: Deduplicate code by adding subed-move-subtitles function, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed f7c04d2 167/389: Fix tests for inserting subtitle(s), ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed c1ee129 181/389: Add functions to adjust start/stop timestamps to player's ones, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 9bf3fcc 213/389: Make timestamp adjustment limitations generic, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 6fd0468 193/389: Use (defalias ...) instead of (fset ...), ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed af4d876 211/389: use emacs 25 for e.g. alist-get, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 9bc42c6 192/389: arg instead of (not (eq nil arg)), ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 7b5c5e0 205/389: Add/Fix tests for moving subtitles, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 3b69f02 225/389: Simplify basic test for moving subtitle, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed b6e484f 204/389: Move subtitles in active region as a unit,
ELPA Syncer <=
- [nongnu] elpa/subed 07a3774 218/389: Add generic function subed-subtitle-id-max, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 80a2545 223/389: Reduce LOC, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed cfe8d1c 228/389: subed-srt--backward-subtitle-id: Don't look for different ID, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 1e2dab9 229/389: remove sharp-quote from list; make variable customizable, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 17b5e1d 238/389: Adjust some test descriptions, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed bd6e798 247/389: subed-copy-player-pos-to-start/stop-time: Return playback position, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed c3e67ec 250/389: Add/Reword some features, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed d27e55a 253/389: Move most stuff from subed.el to subed-common.el, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed b988a17 257/389: subed-replay-adjusted-subtitle-p: Fix if/when in docstring, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 080e512 262/389: Make variable subed-subtitle-format private, ELPA Syncer, 2021/12/03