#+BEGIN_COMMENT
SPDX-FileCopyrightText: 2019-2021 The subed Authors

SPDX-License-Identifier: GPL-3.0-or-later
#+END_COMMENT

* subed
subed is an Emacs major mode for editing subtitles while playing the
corresponding media file with [[https://mpv.io/][mpv]]. At the moment, the only supported
formats are:

- SubRip ( ~.srt~)
- WebVTT ( ~.vtt~ )
- Advanced SubStation Alpha ( ~.ass~, experimental )
- Tab-separated values ( ~.tsv~, experimental ) - as exported by
  Audacity for labels. TSVs are not recognized automatically because
  it's a common data format, but you can use ~subed-tsv-mode~ to turn
  it on in a buffer.

[[file:https://raw.githubusercontent.com/sachac/subed/master/screenshot.jpg]]

** Features

- Jump to next (~M-n~) and previous (~M-p~) subtitle text.
- Jump to the beginning (~C-M-a~) and end (~C-M-e~) of the current
  subtitle's text.
- Merge subtitles with ~M-m~ (~subed-merge-dwim~) and split them with
  ~M-.~ (~subed-split-subtitle~). If the media file is playing in MPV,
  use the current playback position. If not, use the relative position
  in the subtitle text, or other functions listed in
  ~subed-split-subtitle-timestamp-functions~.
- Insert subtitles evenly spaced throughout the available space (~M-i~) or
  right next to the current subtitle (~C-M-i~).  A prefix argument controls how
  many subtitles to insert and whether they are inserted before or after the
  current subtitle.
- Kill subtitles (~M-k~).
- Adjust subtitle start (~M-[~ / ~M-]~) and stop (~M-{~ / ~M-}~) time.  A
  prefix argument sets the number of milliseconds for the current session
  (e.g. ~C-u 1000 M-[ M-[ M-[~ decreases start time by 3 seconds).
- Move the current subtitle or all marked subtitles
  (~subed-move-subtitles~) forward (~C-M-n~) or backward (~C-M-p~) in
  time without changing subtitle duration.  A prefix argument sets the
  number of milliseconds for the current session (e.g. ~C-u 500 C-M-n
  C-M-n~ moves the current subtitle 1 second forward).
- Shift the current subtitle forward (~C-M-f~) or backward (~C-M-b~) together
  with all following subtitles.  This is basically a convenience shortcut for
  ~C-SPC M-> C-M-n/p~.
- Scale all subtitles or all marked subtitles forward (~C-M-x~) or backward
  (~C-M-S-x~) in time without changing subtitle duration.  A prefix argument
  sets the number of milliseconds for the current session (e.g. ~C-u 500
  C-M-x~ moves the last [or last marked] subtitle forward 500ms and
  proportionally scales all [or all marked] subtitles based on this time
  extension.  Similarly, ~C-u 500 C-M-S-x~ moves the last [or last marked]
  subtitle backward 500ms and proportionally scales all [or all marked]
  subtitles based on this time contraction).  This can be extremely useful to
  correct synchronization issues in existing subtitle files.  First, adjust
  the starting time if necessary (e.g. ~C-M-f~), then adjust the ending and
  scale constituent subtitles (e.g. ~C-M-x~).
- Show CPS (characters per second) for the current subtitle.
- Insert HTML-like tags (~C-c C-t C-t~, with an optional attribute
  when prefixed by ~C-u~), in particular italics (~C-c C-t C-i~) or
  boldface (~C-c C-t C-b~).
- SRT: 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.
- Convert between formats with ~M-x subed-convert~.
- Load word timing data (ex: SRV2) using ~M-x
  subed-word-data-load-from-file~.
- Use ~M-x subed-align~ and [[https://www.readbeyond.it/aeneas/][aeneas]] to align your text or subtitles
  with an audio file in order to get timestamps.
  
*** mpv integration (optional)

Using network sockets to control MPV works on Linux and on Mac OS X,
but not on Microsoft Windows due to the lack of Unix-style sockets. On
Microsoft Windows, you will not be able to synchronize with MPV.

- Automatically open the associated media file in MPV based on the filename, open a media file manually with ~C-c C-v~ (~subed-mpv-play-from-file~), or play media directly from a URL with ~C-c C-u~ (~subed-mpv-play-from-url~) . You can customize the automatic detection of files by changing ~subed-video-extensions~ and ~subed-audio-extensions~.
- Pause and resume playback without leaving Emacs (~M-SPC~).
- Jump to the current subtitle in the MPV player with ~M-j~
  (~subed-mpv-jump-to-current-subtitle~). Toggle looping over the
  current subtitle with ~C-c C-l~
  (~subed-toggle-loop-over-current-subtitle~).  Control how many seconds
  to loop before or after the current subtitles by customizing
  ~subed-loop-seconds-before~ and ~subed-loop-seconds-after~.
- Use
  ~C-c .~ (~subed-toggle-sync-point-to-player~) to toggle whether the point should move to the currently playing subtitle.
- Use ~C-c ,~ (~subed-toggle-sync-player-to-point~) to toggle whether mpv should seek to the position of the current subtitle when the point moves between subtitles.
- Subtitles are automatically reloaded in mpv when the buffer is saved.
- Copy the current playback position as start (~C-c [~) or stop (~C-c ]~)
  time of the current subtitle.
- Playback is paused or slowed down when a subtitle's text is edited (~C-c
  C-p~, ~subed-toggle-pause-while-typing~).
- Loop over the current subtitle in mpv (~C-c C-l~).
- When a subtitle's start or stop time changes, mpv seeks to the subtitle's
  start time (~C-c C-r~, ~subed-toggle-replay-adjusted-subtitle~).
- Move one frame forward or backward (~C-c C-f .~ and ~C-c C-f ,~;
  pressing ~,~ or ~.~ afterwards moves by frames until any other
  key is pressed).

** Installation
*** Installing the subed package from NonGNU Elpa
~subed~ is now on [[https://elpa.nongnu.org/nongnu/subed.html][NonGNU ELPA]].  On Emacs 28 and later, you can install it with ~M-x package-install~ ~subed~.

To install it on Emacs 27 or earlier, add the following to your Emacs configuration file:

#+begin_src emacs-lisp :eval no
(with-eval-after-load 'package (add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/")))
#+end_src

Use ~M-x eval-buffer~ to run the code, and then use ~M-x package-install~ ~subed~.
*** Manual installation

If that doesn't work, you can install it manually. To install from the main branch:

#+begin_src sh :eval no
git clone https://github.com/sachac/subed.git
#+end_src

This will create a =subed= directory with the code.

If you have the =make= utility, you can regenerate the autoload definitions with

#+begin_src sh :eval no
make autoloads
#+end_src

If you don't have =make= installed, you can generate the autoloads
with:

#+begin_src sh :eval no
emacs --quick --batch --eval "(progn (setq generated-autoload-file (expand-file-name \"subed-autoloads.el\" \"subed\") backup-inhibited t) \
	(update-directory-autoloads \"./subed\"))"
#+end_src

Then you can add
the following to your Emacs configuration (typically
=~/.config/emacs/init.el=, =~/.emacs.d/init.el=, or =~/.emacs=; you
can create this file if it doesn't exist yet):

#+begin_src emacs-lisp
;; Note the reference to the subed subdirectory
(add-to-list 'load-path "/path/to/subed/subed")
(require 'subed-autoloads)
#+end_src

and reload your configuration with =M-x eval-buffer= or restart Emacs.

If you want to try a branch (ex: =derived-mode=), you can use the
following command inside the =subed= directory:

#+begin_src sh :eval no
git checkout branchname
#+end_src
*** use-package configuration

Here's an example setup if you use use-package:

#+BEGIN_SRC emacs-lisp
(use-package subed
  :ensure t
  :config
  ;; Disable automatic movement of point by default
  (add-hook 'subed-mode-hook 'subed-disable-sync-point-to-player)
  ;; Remember cursor position between sessions
  (add-hook 'subed-mode-hook 'save-place-local-mode)
  ;; Break lines automatically while typing
  (add-hook 'subed-mode-hook 'turn-on-auto-fill)
   ;; Break lines at 40 characters
  (add-hook 'subed-mode-hook (lambda () (setq-local fill-column 40))))
#+END_SRC

*** straight configuration

If you use [[https://github.com/radian-software/straight.el][straight.el]], you can install subed with the following recipe:

#+begin_src emacs-lisp
(straight-use-package '(subed :type git :host github :repo "sachac/subed" :files ("subed/*.el")))
#+end_src

** Getting started

~C-h f subed-mode~ should get you started. This is the parent mode for
~subed-srt-mode~, ~subed-vtt-mode~, and ~subed-ass-mode~. When
manually loading a mode, use those specific format modes instead of
~subed-mode~.
** Troubleshooting
*** subed-mpv: Service name too long

If =subed-mpv-client= reports =(error "Service name too long")=, this
is probably because the path to the socket used to communicate with
MPV is too long for your operating system. You can use =M-x customize=
to set =subed-mpv-socket-dir= to a shorter path.

** Important change in v1.0.0

~subed~ now uses ~subed-srt-mode~, ~subed-vtt-mode~, and
~subed-ass-mode~ instead of directly using ~subed-mode~. These modes
should be automatically associated with the ~.vtt~, ~.srt~, and ~.ass~
extensions. If the generic ~subed-mode~ is loaded instead of the format-specific mode,
you may get an error such as:

#+begin_example
Error in post-command-hook (subed--post-command-handler): (cl-no-applicable-method subed--subtitle-id)
#+end_example

If you set ~auto-mode-alist~ manually in your config, please make sure
you associate extensions the appropriate format-specific mode instead
of ~subed-mode~. The specific backend functions (ex:
~subed-srt--jump-to-subtitle-id~) are also deprecated in favor of
using generic functions such as ~subed-jump-to-subtitle-id~.

** Contributions
   Contributions would be really appreciated! subed conforms to the [[https://reuse.software/spec/][REUSE
   Specification]]; this means that every file has copyright and license
   information. If you modify a file, please update the year shown after
   ~SPDX-FileCopyrightText~. Thank you!

   There's a list of authors in the file ~AUTHORS.org~. If you have at any point
   contributed to subed, you are most welcome to add your name (and email
   address if you like) to the list.

** License
   subed is free software: you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
   Foundation, either version 3 of the License, or (at your option) any later
   version.

   This program is distributed in the hope that it will be useful but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   FOR A PARTICULAR PURPOSE.  See the [[https://www.gnu.org/licenses/gpl-3.0.txt][GNU General Public License]] for more
   details.

#+STARTUP: showeverything
#+OPTIONS: num:nil
#+OPTIONS: ^:{}
