[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/subed 7e04e16 013/389: Use C-u ... when inserting subtitle
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/subed 7e04e16 013/389: Use C-u ... when inserting subtitles |
Date: |
Fri, 3 Dec 2021 10:59:47 -0500 (EST) |
branch: elpa/subed
commit 7e04e1603f0c484cbd7a86c3d96114e44209a2d6
Author: Random User <rndusr@posteo.de>
Commit: Random User <rndusr@posteo.de>
Use C-u ... when inserting subtitles
---
subed/subed-config.el | 10 +++
subed/subed-srt.el | 88 ++++++++++++++++----
tests/test-subed-srt.el | 217 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 299 insertions(+), 16 deletions(-)
diff --git a/subed/subed-config.el b/subed/subed-config.el
index b9ed926..62b7e66 100644
--- a/subed/subed-config.el
+++ b/subed/subed-config.el
@@ -129,6 +129,16 @@ typed something.")
"Whether the player was paused by the user or automatically.")
+(defcustom subed-subtitle-spacing 100
+ "How many milliseconds to keep between subtitles."
+ :type 'integer
+ :group 'subed)
+
+(defcustom subed-default-subtitle-length 1.0
+ "How long to make subtitles in seconds when inserted after the last
subtitle."
+ :type 'float
+ :group 'subed)
+
(defcustom subed-loop-seconds-before 0
"When looping over a single subtitle, start the loop this many
seconds before the subtitle starts."
diff --git a/subed/subed-srt.el b/subed/subed-srt.el
index 9f0dbb4..d97a5db 100644
--- a/subed/subed-srt.el
+++ b/subed/subed-srt.el
@@ -309,22 +309,78 @@ Return point or nil if there is no previous subtitle."
(interactive)
(subed-srt--adjust-subtitle-stop-relative -100))
-;; TODO: Write tests
-;; TODO: Implement support for prefix argument to
-;; - insert n subtitles with C-u n M-i.
-;; - insert 1 subtitle before the current one with C-u M-i.
-(defun subed-srt-subtitle-insert ()
- "Insert a subtitle after the current."
- (interactive)
- (let ((start-time (+ (subed-srt--subtitle-msecs-stop) 100))
- (stop-time (- (save-excursion
- (subed-srt-forward-subtitle-id)
- (subed-srt--subtitle-msecs-start)) 100)))
- (subed-srt-forward-subtitle-id)
- (insert (format "1\n%s --> %s\n\n\n"
- (subed-srt--msecs-to-timestamp start-time)
- (subed-srt--msecs-to-timestamp stop-time))))
- (previous-line 2))
+(defun subed-srt-subtitle-insert (arg)
+ "Insert subtitle(s).
+`universal-argument' is used in the following manner:
+ \\[subed-subtitle-insert] Insert 1 subtitle after the current
subtitle
+ \\[universal-argument] - \\[subed-subtitle-insert] Insert 1 subtitle
before the current subtitle
+ \\[universal-argument] 5 \\[subed-subtitle-insert] Insert 5 subtitles
after the current subtitle
+ \\[universal-argument] - 5 \\[subed-subtitle-insert] Insert 5 subtitles
before the current subtitle
+ \\[universal-argument] \\[subed-subtitle-insert] Insert 1 subtitle
before the current subtitle
+ \\[universal-argument] \\[universal-argument] \\[subed-subtitle-insert]
Insert 2 subtitles before the current subtitle"
+ (interactive "P")
+ (let* ((number-of-subs (cond ((eq arg nil) 1) ;; M-i
+ ((integerp arg) arg) ;; C-u N M-i / C-u - N
M-i
+ ;; C-u [C-u ...] M-i / C-u - [C-u ...] M-i
+ ((consp arg) (* (truncate (log (abs (car arg))
4)) ;; ([-]64) -> 3
+ (/ (car arg) (abs (car arg)))))
;; Restore sign
+ (t 1))) ;; C-u - M-i (Is there
anything else is left?)
+ (insert-before (or (< number-of-subs 0) ;; C-u - N M-i
+ (eq arg '-) ;; C-u - M-i
+ (consp arg))) ;; C-u [C-u ...] M-i
+ ;; Ensure number-of-subs is positive, now that we figured out
`insert-before'
+ (number-of-subs (abs number-of-subs)))
+ (subed-debug "Inserting %s subtitle(s) %s the current" number-of-subs (if
insert-before "before" "after"))
+ (subed-srt-move-to-subtitle-id)
+ ;; Move to the ID of the subtitle we're prepending subtitles to so that we
+ ;; can do (insert "<new subtitle>")
+ (if insert-before
+ (subed-srt-move-to-subtitle-id)
+ (when (and (not (subed-srt-forward-subtitle-id)) ;; Appending after last
subtitle
+ (> (buffer-size) 0)) ;; Buffer is not empty
+ ;; There is no ID because we're appending to the last subtitle. We
just
+ ;; have to make sure there is a subtitle delimiter ("\n\n") after the
+ ;; last subtitle and point is where the new ID will go.
+ (subed-srt-move-to-subtitle-end)
+ (forward-line)
+ (insert "\n")))
+ ;; Insert subtitles
+ (save-excursion
+ ;; Find out how much time we have per subtitle
+ (let*
+ ;; nil when there's no previous subtitle
+ ((prev-stop-msecs (save-excursion (when
(subed-srt-backward-subtitle-id)
+
(subed-srt--subtitle-msecs-stop))))
+ ;; nil when there's no next subtitle
+ (next-start-msecs (when (looking-at "^[0-9]$")
+ (subed-srt--subtitle-msecs-start)))
+ ;; nil when there's no next subtitle
+ (available-msecs (when next-start-msecs
+ (- next-start-msecs (or prev-stop-msecs 0))))
+ ;; Calculate milliseconds per inserted subtitle or use default value
+ ;; if we're appending to the last subtitle
+ (sub-msecs (if available-msecs (/ available-msecs number-of-subs)
+ (* subed-default-subtitle-length 1000))))
+ (dotimes (i number-of-subs)
+ (let* ((start-msecs (+ (or prev-stop-msecs 0) (* sub-msecs i)))
+ (stop-msecs (+ start-msecs sub-msecs))
+ ;; Apply `subed-subtitle-spacing'
+ (start-msecs-spaced (if (= i 0)
+ (+ start-msecs subed-subtitle-spacing)
+ (+ start-msecs (/
subed-subtitle-spacing 2))))
+ (stop-msecs-spaced (if (= i (1- number-of-subs))
+ (- stop-msecs subed-subtitle-spacing)
+ (- stop-msecs (/ subed-subtitle-spacing
2)))))
+ (insert (format "0\n%s --> %s\n\n\n"
+ (subed-srt--msecs-to-timestamp start-msecs-spaced)
+ (subed-srt--msecs-to-timestamp
stop-msecs-spaced))))))
+ ;; If we're not on an ID, that means we added one or more subtitles after
+ ;; the last one and we can remove the trailing extra newline
+ (when (looking-at "^[[:space:]]*$")
+ (forward-line -1)
+ (kill-whole-line)))
+ (subed-srt--regenerate-ids)
+ (subed-srt-move-to-subtitle-text)))
;; TODO: Implement support for prefix argument to
;; kill n subtitles with C-u n M-k.
diff --git a/tests/test-subed-srt.el b/tests/test-subed-srt.el
index 2e26458..94a7d3b 100644
--- a/tests/test-subed-srt.el
+++ b/tests/test-subed-srt.el
@@ -378,6 +378,223 @@ Baz.
"Baz.\n"))))
)
+(describe "Inserting"
+ (describe "in an empty buffer,"
+ (describe "appending"
+ (it "a single subtile."
+ (cl-loop for arg in (list nil 1) do
+ (with-temp-buffer
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:00:00,100 --> 00:00:00,900\n\n"))
+ (expect (point) :to-equal 33))))
+ (it "multiple subtiles."
+ (cl-loop for arg in (list 2) do
+ (with-temp-buffer
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:00:00,100 --> 00:00:00,950\n\n\n"
+
"2\n"
+
"00:00:01,050 --> 00:00:01,900\n\n"))
+ (expect (point) :to-equal 33)))))
+ (describe "prepending"
+ (it "a single subtile."
+ (cl-loop for arg in (list '- -1 (list 4)) do
+ (with-temp-buffer
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:00:00,100 --> 00:00:00,900\n\n"))
+ (expect (point) :to-equal 33))))
+ (it "multiple subtiles."
+ (cl-loop for arg in (list -2 (list -16)) do
+ (with-temp-buffer
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:00:00,100 --> 00:00:00,950\n\n\n"
+
"2\n"
+
"00:00:01,050 --> 00:00:01,900\n\n"))
+ (expect (point) :to-equal 33)))))
+ )
+
+ (describe "in a non-empty buffer"
+ (describe "before the current subtitle"
+ (it "a single subtitle."
+ (cl-loop for arg in (list '- -1 (list 4)) do
+ (with-temp-buffer
+ (insert mock-srt-data)
+ (subed-srt-move-to-subtitle-text
2)
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:01:01,000 --> 00:01:05,123\n"
+
"Foo.\n\n"
+
"2\n"
+
"00:01:05,223 --> 00:02:02,134\n"
+
"\n\n"
+
"3\n"
+
"00:02:02,234 --> 00:02:10,345\n"
+
"Bar.\n\n"
+
"4\n"
+
"00:03:03,456 --> 00:03:15,567\n"
+
"Baz.\n"))
+ (expect (point) :to-equal 71))))
+ (it "multiple subtitles."
+ (cl-loop for arg in (list -2 (list 16)) do
+ (with-temp-buffer
+ (insert mock-srt-data)
+ (subed-srt-move-to-subtitle-text
2)
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:01:01,000 --> 00:01:05,123\n"
+
"Foo.\n\n"
+
"2\n"
+
"00:01:05,223 --> 00:01:33,628\n"
+
"\n\n"
+
"3\n"
+
"00:01:33,728 --> 00:02:02,133\n"
+
"\n\n"
+
"4\n"
+
"00:02:02,234 --> 00:02:10,345\n"
+
"Bar.\n\n"
+
"5\n"
+
"00:03:03,456 --> 00:03:15,567\n"
+
"Baz.\n"))
+ (expect (point) :to-equal 71))))
+ )
+ (describe "after the current subtitle"
+ (it "a single subtitle."
+ (cl-loop for arg in (list nil 1) do
+ (with-temp-buffer
+ (insert mock-srt-data)
+ (subed-srt-move-to-subtitle-text
1)
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:01:01,000 --> 00:01:05,123\n"
+
"Foo.\n\n"
+
"2\n"
+
"00:01:05,223 --> 00:02:02,134\n"
+
"\n\n"
+
"3\n"
+
"00:02:02,234 --> 00:02:10,345\n"
+
"Bar.\n\n"
+
"4\n"
+
"00:03:03,456 --> 00:03:15,567\n"
+
"Baz.\n"))
+ (expect (point) :to-equal 71))))
+ (it "multiple subtitles."
+ (cl-loop for arg in (list 2) do
+ (with-temp-buffer
+ (insert mock-srt-data)
+ (subed-srt-move-to-subtitle-text
1)
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:01:01,000 --> 00:01:05,123\n"
+
"Foo.\n\n"
+
"2\n"
+
"00:01:05,223 --> 00:01:33,628\n"
+
"\n\n"
+
"3\n"
+
"00:01:33,728 --> 00:02:02,133\n"
+
"\n\n"
+
"4\n"
+
"00:02:02,234 --> 00:02:10,345\n"
+
"Bar.\n\n"
+
"5\n"
+
"00:03:03,456 --> 00:03:15,567\n"
+
"Baz.\n"))
+ (expect (point) :to-equal 71))))
+ )
+
+
+ (describe "before the first subtitle"
+ (it "a single subtitle."
+ (cl-loop for arg in (list '- -1 (list 4)) do
+ (with-temp-buffer
+ (insert mock-srt-data)
+ (subed-srt-move-to-subtitle-text
1)
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:00:00,100 --> 00:01:00,900\n"
+
"\n\n"
+
"2\n"
+
"00:01:01,000 --> 00:01:05,123\n"
+
"Foo.\n\n"
+
"3\n"
+
"00:02:02,234 --> 00:02:10,345\n"
+
"Bar.\n\n"
+
"4\n"
+
"00:03:03,456 --> 00:03:15,567\n"
+
"Baz.\n"))
+ (expect (point) :to-equal 33))))
+ (it "multiple subtitles."
+ (cl-loop for arg in (list -2 (list 16)) do
+ (with-temp-buffer
+ (insert mock-srt-data)
+ (subed-srt-move-to-subtitle-text
1)
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:00:00,100 --> 00:00:30,450\n"
+
"\n\n"
+
"2\n"
+
"00:00:30,550 --> 00:01:00,900\n"
+
"\n\n"
+
"3\n"
+
"00:01:01,000 --> 00:01:05,123\n"
+
"Foo.\n\n"
+
"4\n"
+
"00:02:02,234 --> 00:02:10,345\n"
+
"Bar.\n\n"
+
"5\n"
+
"00:03:03,456 --> 00:03:15,567\n"
+
"Baz.\n"))
+ (expect (point) :to-equal 33))))
+ )
+
+
+ (describe "after the last subtitle"
+ (it "a single subtitle."
+ (cl-loop for arg in (list nil 1) do
+ (with-temp-buffer
+ (insert mock-srt-data)
+ (subed-srt-move-to-subtitle-text
3)
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:01:01,000 --> 00:01:05,123\n"
+
"Foo.\n\n"
+
"2\n"
+
"00:02:02,234 --> 00:02:10,345\n"
+
"Bar.\n\n"
+
"3\n"
+
"00:03:03,456 --> 00:03:15,567\n"
+
"Baz.\n\n"
+
"4\n"
+
"00:03:15,667 --> 00:03:16,467\n"
+
"\n"))
+ (expect (point) :to-equal 147))))
+ (it "multiple subtitles."
+ (cl-loop for arg in (list 2) do
+ (with-temp-buffer
+ (insert mock-srt-data)
+ (subed-srt-move-to-subtitle-text
3)
+ (subed-srt-subtitle-insert arg)
+ (expect (buffer-string) :to-equal
(concat "1\n"
+
"00:01:01,000 --> 00:01:05,123\n"
+
"Foo.\n\n"
+
"2\n"
+
"00:02:02,234 --> 00:02:10,345\n"
+
"Bar.\n\n"
+
"3\n"
+
"00:03:03,456 --> 00:03:15,567\n"
+
"Baz.\n\n"
+
"4\n"
+
"00:03:15,667 --> 00:03:16,517\n"
+
"\n\n"
+
"5\n"
+
"00:03:16,617 --> 00:03:17,467\n"
+
"\n"))
+ (expect (point) :to-equal 147))))
+ )
+ )
+ )
(describe "Sanitizing"
(it "removes trailing tabs and spaces from all lines."
- [nongnu] elpa/subed c04670a 007/389: Adjust some docstrimgs, (continued)
- [nongnu] elpa/subed c04670a 007/389: Adjust some docstrimgs, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed c5dcb73 010/389: Make closing parens spoon each other, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 8a39911 024/389: Use let instead of setq, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 78d3855 026/389: subed-srt-move-to-subtitle-id: Use let instead of setq, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed c895b91 012/389: Add test for sanitizing on empty subtitle texts, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 6797d10 028/389: Use lexical scoping, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 7939e0a 022/389: Move function to have same order as tests, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 31f8255 016/389: README: Turns out spaces are not the issue, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 27c8141 014/389: Some work on README, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 6b97e24 023/389: Fix test's description, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 7e04e16 013/389: Use C-u ... when inserting subtitles,
ELPA Syncer <=
- [nongnu] elpa/subed 005c0cc 027/389: Remove TODO for C-u N M-k, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed fd737b7 035/389: Use save-excursion in subed--save-excursion, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 0815e10 047/389: Simplify subed-srt--regexp-duration, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed bbd239a 042/389: subed-srt--regenerate-ids: Wrap function body in atomic-change-group, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 8790abf 048/389: Add subed-srt-validate, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 7d76a35 049/389: Simplify subed-srt-move-to-subtitle-text, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 821b259 045/389: subed-srt--regenerate-ids: Make this a public function, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed d3d2013 050/389: Look for stop time only on the relevant line, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 042941c 051/389: Fix docstrings, ELPA Syncer, 2021/12/03
- [nongnu] elpa/subed 4e50796 052/389: Fix subed-srt-backward-subtitle-id, ELPA Syncer, 2021/12/03