detubifier.el (8918B)
1 ;;; detubifier.el --- Kill text and replace youtube.com and youtu.be or whatever domain with whatever the fuck you want. -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2024 Yuval Langer 4 5 ;; Author: Yuval Langer <yuval.langer@gmail.com> 6 ;; Version: 0.3.0 7 ;; Keywords: web, youtube 8 ;; URL: https://codebarg.org/kakafarm/emacs-detubifier-mode/ 9 10 11 ;; This program is free software: you can redistribute it and/or modify 12 ;; it under the terms of the GNU Affero General Public License as 13 ;; published by the Free Software Foundation, either version 3 of the 14 ;; License, or (at your option) any later version. 15 16 ;; This program is distributed in the hope that it will be useful, 17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 ;; GNU Affero General Public License for more details. 20 21 ;; You should have received a copy of the GNU Affero General Public License 22 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 23 24 ;;; Commentary: 25 26 ;; Usage: 27 ;; 28 ;; Let's say you have the text 29 ;; "https://twitter.com/Nadav_Eyal/status/1809975194926055629" and 30 ;; would rather have something like 31 ;; "https://nitter.poast.org/Nadav_Eyal/status/1809975194926055629" 32 ;; instead. A possible solution is to: 33 ;; 34 ;; 0. Set up `detubifier-regexp-replacement-pairs'. 35 ;; 1. Mark that text. 36 ;; 2. Kill it. 37 ;; 3. Run `detubifier-regexp-replacement-pairs'. 38 ;; 4. Yank it in your chat room. 39 40 ;;; Code: 41 42 (require 'browse-url) 43 44 (defgroup detubifier '() 45 "Replace the usual enshittified suspects with nonenshittified front end services." 46 :group 'communcation) 47 48 (defcustom detubifier-regexp-replacement-pairs 49 `((,(rx "https://www.youtube.com/") . "https://invidious.jing.rocks/") 50 (,(rx "https://youtube.com/") . "https://invidious.jing.rocks/") 51 (,(rx "https://youtu.be/") . "https://invidious.jing.rocks/watch?v=") 52 (,(rx "https://twitter.com/") . "https://nitter.poast.org/") 53 (,(rx "https://x.com/") . "https://farside.link/")) 54 "List of pairs, each with a regexp and its replacement." 55 :type '(repeat (cons regexp string)) 56 :group 'detubifier 57 ) 58 59 (defcustom detubifier-farside-url 60 "https://farside.link/" 61 "Base address to the farside service." 62 :type 'string 63 :group 'detubifier 64 ) 65 66 (defcustom detubifier-detubifying-method 67 'farside 68 "Method of detubifying." 69 :type '(radio (symbol farside) 70 (symbol custom)) 71 :group 'detubifier 72 ) 73 74 (defcustom detubifier-enshittified-urls 75 '( 76 "https://reddit.com/" 77 "https://twitter.com/" 78 "https://www.reddit.com/" 79 "https://www.twitter.com/" 80 "https://www.youtube.com/" 81 "https://x.com/" 82 "https://youtu.be/" 83 "https://youtube.com/" 84 ) 85 "URLs of enshittified services." 86 :type '(repeat string) 87 :group 'detubifier 88 ) 89 90 ;;;###autoload 91 (defun detubifier-browse-url (url &rest args) 92 "Open URL using `browse-url' with the usual suspect URLs replaced. 93 94 Replace the usual suspect URLs with the method chosen by the 95 `detubifier-detubifying-method' custom variable. 96 97 ARGS is passed as the ARGS of `browse-url'. 98 99 TODO: What are args in `browse-url'?" 100 101 (interactive (browse-url-interactive-arg "URL: ")) 102 103 (pcase detubifier-detubifying-method 104 ('farside (browse-url (detubifier-farsidify-string url) args)) 105 ('custom (browse-url (detubifier-custom-detubify-string url) args)))) 106 107 ;;;###autoload 108 (defun detubifier-custom-detubify-region (beg end) 109 "Replace the usual suspect URLs in region. 110 111 Region is defined either by (region-beginning) and (region-end), 112 or, if provided, between between BEG and END. 113 114 Use custom variable `detubifier-regexp-replacement-pairs' to do so." 115 116 (interactive (list (region-beginning) 117 (region-end))) 118 119 (save-excursion 120 (pcase-dolist (`(,current-regexp . ,current-replacement) 121 detubifier-regexp-replacement-pairs) 122 (replace-regexp-in-region current-regexp 123 current-replacement 124 beg 125 end)))) 126 127 ;;;###autoload 128 (defun detubifier-custom-detubify-string (str) 129 "Replace the usual suspect URLs in string STR. 130 131 Use custom variable `detubifier-regexp-replacement-pairs' to do so." 132 133 (let ((str str)) 134 (pcase-dolist (`(,current-regexp . ,current-replacement) 135 detubifier-regexp-replacement-pairs) 136 (setq str (replace-regexp-in-string current-regexp 137 current-replacement 138 str))) 139 str)) 140 141 ;;;###autoload 142 (defun detubifier-detubify-top-kill () 143 "Replace all occurances of the usual suspects in the top of the kill ring. 144 145 Use the method chosen by the `detubifier-detubifying-method' custom variable." 146 147 (interactive) 148 149 (save-excursion 150 (with-temp-buffer 151 (yank) 152 (goto-char (point-min)) 153 (pcase detubifier-detubifying-method 154 ('farside (detubifier-farsidify-region (point-min) (point-max))) 155 ('custom (detubifier-custom-detubify-region (point-min) (point-max)))) 156 (kill-region (point-min) (point-max)))) 157 ) 158 159 ;;;###autoload 160 (defun detubifier-farsidify-region (beg end) 161 "Prefix `detubifier-farside-url' the usual suspect URLs in a region. 162 163 Region is defined either by (region-beginning) and (region-end), 164 or, if provided, between between BEG and END. 165 166 The usual suspects are replaced in this way: 167 168 example.com/blah/blah 169 170 is replaced with: 171 172 https://farside.link/example.com/blah/blah" 173 174 (interactive (list (region-beginning) 175 (region-end))) 176 177 (save-excursion 178 (save-restriction ;; Save narrowing setting and revert to it when finishing. 179 (narrow-to-region beg end) 180 (rx-let-eval `((urls () (group (or ,@detubifier-enshittified-urls)))) 181 (let ((r (rx-to-string '(urls)))) 182 (replace-regexp-in-region r 183 (concat detubifier-farside-url "\\1") 184 beg 185 end)))))) 186 187 ;;;###autoload 188 (defun detubifier-farsidify-string (str) 189 "Prefix `detubifier-farside-url' the usual suspects URLs in string STR." 190 191 (rx-let-eval `((urls () (group (or ,@detubifier-enshittified-urls)))) 192 (replace-regexp-in-string (rx-to-string '(urls)) 193 (concat detubifier-farside-url "\\1") 194 str)) 195 ) 196 197 (define-obsolete-function-alias 198 'detubifier-replace-contents 199 'detubifier-detubify-top-kill 200 "2024-09-25") 201 202 ;;; Testing: 203 204 (ert-deftest test-detubifier-farsidify-string () 205 "Test `detubifier-farsidify-string'." 206 (should (equal (detubifier-farsidify-string "sdfljdsf sdfkjl https://youtube.com/moo 207 https://twitter.com/blah") 208 (concat "sdfljdsf sdfkjl " 209 detubifier-farside-url 210 "https://youtube.com/moo 211 " 212 detubifier-farside-url 213 "https://twitter.com/blah")))) 214 215 (ert-deftest test-detubifier-farsidify-region () 216 "Test `detubifier-farsidify-region'." 217 (with-temp-buffer 218 (should (equal (let () 219 (insert "sdfljdsf sdfkjl https://youtube.com/moo 220 https://twitter.com/blah") 221 (detubifier-farsidify-region (point-min) 222 (point-max)) 223 (buffer-substring-no-properties (point-min) 224 (point-max))) 225 (concat "sdfljdsf sdfkjl " 226 detubifier-farside-url 227 "https://youtube.com/moo 228 " 229 detubifier-farside-url 230 "https://twitter.com/blah"))))) 231 232 (ert-deftest test-detubifier-custom-detubify-string () 233 "Test `detubifier-custom-detubify-string'. 234 235 TODO: Test only works with the default `detubifier-regexp-replacement-pairs'. 236 Make it work in general!" 237 (should (equal (detubifier-custom-detubify-string "sdfljdsf sdfkjl https://youtube.com/moo 238 https://twitter.com/blah") 239 (concat "sdfljdsf sdfkjl https://invidious.jing.rocks/moo 240 https://nitter.poast.org/blah")))) 241 242 (ert-deftest test-detubifier-custom-detubify-region () 243 "Test `detubifier-custom-detubify-region'. 244 245 TODO: Test only works with the default `detubifier-regexp-replacement-pairs'. 246 Make it work in general!" 247 (with-temp-buffer 248 (should (equal (let () 249 (insert "sdfljdsf sdfkjl https://youtube.com/moo 250 https://twitter.com/blah") 251 (detubifier-custom-detubify-region (point-min) 252 (point-max)) 253 (buffer-substring-no-properties (point-min) 254 (point-max))) 255 (concat "sdfljdsf sdfkjl https://invidious.jing.rocks/moo 256 https://nitter.poast.org/blah"))))) 257 258 (provide 'detubifier) 259 ;;; detubifier.el ends here