From 0bc96fb6e1bf8f91855f00f6c7e07142cecd0aab Mon Sep 17 00:00:00 2001 From: pi-bot-01 Date: Thu, 26 Mar 2026 01:01:07 -0700 Subject: [PATCH] Initial commit --- nov.el | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 nov.el diff --git a/nov.el b/nov.el new file mode 100644 index 0000000..4cd75ac --- /dev/null +++ b/nov.el @@ -0,0 +1,120 @@ +;;; Provides functions to make reading novels in eww easier. + +(defun eww-new-buffer () + "open new empty eww buffer" + (interactive) + (switch-to-buffer (generate-new-buffer "*eww*")) + (eww-mode)) + +(defun next-chapter () + "eww follow link to next chapter" + (interactive) + (defvar-local next-chapter-heur "[nN]ext.*?[cC]hapter") + (if (re-search-forward next-chapter-heur nil t) + (progn + (backward-char) + (eww-follow-link)) + (message "next chapter link not found"))) + +(defun prev-chapter () + "eww follow link to previous chapter" + (interactive) + (defvar-local prev-chapter-heur "[pP]rev.*?[cC]hapter") + (if (re-search-forward prev-chapter-heur nil t) + (progn + (backward-char) + (eww-follow-link)) + (message "prev chapter link not found"))) + +(defun goto-chapter () + "move cursor to next occurence of chapter" + (interactive) + ;; (defvar-local chapter-heur "^.*chapter.*[[:digit:]].*") + (defvar-local chapter-heur "^chapter.*[[:digit:]].*") + (re-search-forward chapter-heur (buffer-end 1) t) + (recenter-top-bottom 0)) + +(defun re-seq (regexp string) + "Get a list of all regexp matches in a string" + (save-match-data + (let ((pos 0) + matches) + (while (string-match regexp string pos) + (push (match-string 0 string) matches) + (setq pos (match-end 0))) + matches))) + +(defun map-insert-columnized (SEQ &optional cols) + "insert sequence in columnized form" + (unless cols + (setq-local cols 8)) + (setq-local counter 0) + (while SEQ + (insert (car SEQ)) + (setq-local SEQ (cdr SEQ)) + (setq-local counter (+ counter 1)) + (if (eq counter cols) + (progn + (insert "\n") + (setq-local counter 0))))) + +(defun xah-clean-whitespace () + "Delete trailing whitespace, and replace repeated blank lines to just 1. +Only space and tab is considered whitespace here. +Works on whole buffer or text selection, respects `narrow-to-region'. + +URL `http://ergoemacs.org/emacs/elisp_compact_empty_lines.html' +Version 2017-09-22" + (interactive) + (let ($begin $end) + (if (region-active-p) + (setq $begin (region-beginning) $end (region-end)) + (setq $begin (point-min) $end (point-max))) + (save-excursion + (save-restriction + (narrow-to-region $begin $end) + (progn + (goto-char (point-min)) + (while (re-search-forward "[ \t]+\n" nil "move") + (replace-match "\n"))) + (progn + (goto-char (point-min)) + (while (re-search-forward "\n\n\n+" nil "move") + (replace-match "\n\n"))) + (progn + (goto-char (point-max)) + (while (equal (char-before) 32) ; char 32 is space + (delete-char -1)))) + (message "white space cleaned")))) + +(defun my-clean-whitespace () + "Performs xah-clean-whitespace on read only buffers." + (interactive) + (if buffer-read-only + (progn + (read-only-mode 0) + (xah-clean-whitespace) + (read-only-mode 1)) + (progn + (xah-clean-whitespace)))) + +(defun eww-open-url-in-new-buffer (&optional URL) + "Opens given url new new eww buffer." + (interactive) + (or URL + (setq URL + (read-string "URL: "))) + (eww-new-buffer) + (eww URL)) + +(defun eww-bookmark-browse-in-new-buffer () + "Browse the bookmark under point in new eww buffer." + (interactive) + (let ((bookmark (get-text-property (line-beginning-position) 'eww-bookmark))) + (unless bookmark + (user-error "No bookmark on the current line")) + (quit-window) + (eww-new-buffer) + (eww-browse-url (plist-get bookmark :url)))) + +(provide 'nov)