diff --git a/README.md b/README.md index ea1a6ed..b1ea7f3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ +> [!CAUTION] +> This software is now being maintained on [Codeberg](https://codeberg.org/scip/novel-mode/). + # novel-mode + Emacs Screen Reader # Demo diff --git a/demo.gif b/demo.gif deleted file mode 100644 index 285a6b6..0000000 Binary files a/demo.gif and /dev/null differ diff --git a/novel-mode.el b/novel-mode.el deleted file mode 100644 index 132eb56..0000000 --- a/novel-mode.el +++ /dev/null @@ -1,433 +0,0 @@ -;;; novel-mode.el --- screen reader - -;; Copyright (C) 2016, T.v.Dein - -;; This file is NOT part of Emacs. - -;; This program 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 2 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 GNU -;; General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with this program; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -;; USA - -;; Version: 0.01 -;; Author: T.v.Dein -;; Keywords: read books novels -;; URL: https://codeberg.org/scip/novel-mode -;; License: GNU General Public License >= 2 - -;;; Commentary: - -;; Novel mode is a minor mode which converts emacs into a screen -;; reader, or in other words, it enables distraction free reading. It -;; is however not suited for distraction free editing. Try writeroom -;; mode if you're looking for this. - -;; When turned on, it does the following conversions: - -;; - disable almost all distractions, as menu, toolbar, scrollbar -;; - enlarge font size -;; - switch to variable width font -;; - enable word wrap (without fringe marker) -;; - increase line spacing -;; - add a window margin to the left and right (thereby centering the text) -;; - disable all input keys (rendering the buffer read-only) -;; - disable the cursor -;; - switch to buffer-scrolling (like e.g. in Acroread) -;; - display current reading position in percent -;; - add a couple of convenience one-key commands - -;; Novel mode provides the following one-key commands, when active: - -;; n scroll one page down -;; p scroll one page up -;; scroll one line down -;; scroll one line up -;; mousewheel scroll linewise up or down -;; SPC scroll one page down -;; increase margins, makes visible text narrower -;; decrease margins, makes visible text wider -;; + increase font size -;; - decrease font size -;; i invert video display -;; q quit novel mode -;; ? display key mapping - -;; Important: while normal key input (beside the ones listed above), -;; is disabled, Control and Meta still work, of course. Please be also -;; aware that this mode might conflict with god-mode or evil-mode. - -;; If you use this mode quite often, then it might be a good idea to -;; use save-place mode, so that a text file will be opened where you -;; left last time (just like any ebook reader would do. Here's how to -;; do that: - -;; (if (version< emacs-version "25.0") -;; (progn -;; (require 'saveplace) -;; (setq-default save-place t)) -;; (save-place-mode 1)) - - -;; The name novel mode is not my idea, there's a function on Xah's -;; ergomacs page with a function for this kind of stuff: -;; http://ergoemacs.org/emacs/emacs_novel_reading_mode.html. In fact, -;; this mode is based on this function, I had it in my .emacs file and -;; enhanced it all the time. At some point it made more sence to -;; maintain this baby in its own mode - hence novel-mode. - -;;; Install: - -;; To use, save novel-mode.el to a directory in your load-path. - -;; Add something like this to your config: - -;; (require 'novel-mode) -;; (add-hook 'text-mode-hook 'novel-mode) - -;; or load it manually, when needed: - -;; M-x novel-mode - -;;; Customize: - -;; You can customize the following variables: - -;; To setup a default left and right margin, use this: - -;; (setq novel-default-margin 50) - -;; All available novel-mode variables can be modified interactively -;; with: - -;; M-x customize-group RET novel-mode RET - -;; You can also use hooks to novel mode as a way to modify or enhance -;; its behavior. The following hooks are available: - -;; novel-mode-pre-start-hook -;; novel-mode-post-start-hook -;; novel-mode-pre-stop-hook -;; novel-mode-post-stop-hook - -;; Example: - -;; (add-hook 'novel-mode-post-start-hook -;; (lambda () -;; (set-face-font 'default "DejaVu Sans"))) -;; (add-hook 'novel-mode-post-stop-hook -;; (lambda () -;; (set-face-font 'default "Courier"))) - - - - -;;; Code: -;;;; Constants: - -(defconst novel-mode-versioni "0.01" "Novel mode version") - -(defgroup novel-mode nil - "screen reader mode" - :group 'extensions - :group 'tools - :link '(url-link :tag "Repository" "https://codeberg.org/scip/novel-mode")) - -;; various vars to remember previous states -(defvar novel--mlf nil) -(defvar novel--vlm nil) -(defvar novel--ww nil) -(defvar novel--mbm nil) -(defvar novel--tbm nil) -(defvar novel--sbm nil) -(defvar novel--ct nil) - -;; set on startup -(defvar novel--max-margin nil) -(defvar novel--cur-margin nil) - -;; remember last invertion state, if any. we start with t by purpose, keep this -(defvar novel--invert-state t) - - -;;;; Customizable variables: - -(defcustom novel-default-margin nil - "Initial margin (used left+right) in chars, calculated if nil.") - -(defcustom novel-feedback nil - "Display feedback in minibuffer on actions") - - -;;;; Internal Functions: - -(defun novel--cursor-pos() - "return current cursor position in %" - ;; percent code stolen shamelessly from simple.el/what-cursor-position - (interactive) - (let* ((total (buffer-size)) - (pos (point)) - (percent (if (> total 50000) - ;; Avoid overflow from multiplying by 100! - (/ (+ (/ total 200) (1- pos)) (max (/ total 100) 1)) - (/ (+ (/ total 2) (* 100 (1- pos))) (max total 1))))) - (message "%S%%" percent))) - -(defun novel--set-margins() - "Set window margins" - (interactive) - (set-window-margins nil novel--cur-margin novel--cur-margin) - (when novel-feedback - (message "set window margins to: %S (max: %S)" - novel--cur-margin novel--max-margin))) - - -;; disable self-insert-command. -;; remap code by Thorsten Jolitz, outshine.el, GPL2.0+ -(defun novel--self-insert-command(N) - (interactive "c") - (message "try ?")) - -(defun novel--remap-self-insert() - (novel--remap novel-mode-map 'self-insert-command 'novel--self-insert-command)) - -(defun novel--reset-remap-self-insert() - (novel--remap novel-mode-map 'novel--self-insert-command 'self-insert-command)) - -(defun novel--defkey (keymap key def) - "Define a KEY in a KEYMAP with definition DEF." - (define-key keymap key def)) - -(defun novel--remap (map &rest commands) - "In MAP, remap the functions given in COMMANDS. -COMMANDS is a list of alternating OLDDEF NEWDEF command names." - (let (new old) - (while commands - (setq old (pop commands) new (pop commands)) - (if (fboundp 'command-remapping) - (novel--defkey map (vector 'remap old) new) - (substitute-key-definition old new map global-map))))) - -(defun novel--backup-states() - "Store current states in variables for later restoration" - ;; various vars to remember previous states - (setq novel--mlf mode-line-format - novel--vlm visual-line-mode - novel--ww word-wrap - novel--mbm menu-bar-mode - novel--tbm tool-bar-mode - novel--ct cursor-type - novel--sbm scroll-bar-mode)) - - -;;;; Hooks: - -(defvar novel-mode-pre-start-hook () - "Called before startup") - -(defvar novel-mode-post-start-hook () - "Called after startup") - -(defvar novel-mode-pre-stop-hook () - "Called before stopping") - -(defvar novel-mode-post-stop-hook () - "Called after stopping") - -;;;; API Functions: - -(defun novel-up() - "Scroll buffer one line up" - (interactive) - (scroll-down 1) - (novel--cursor-pos)) - -(defun novel-down() - "Scroll buffer one line down" - (interactive) - (scroll-up 1) - (novel--cursor-pos)) - -(defun novel-page-up() - "Scroll buffer one page up" - (interactive) - (scroll-down) - (novel--cursor-pos)) - -(defun novel-page-down() - "Scroll buffer one page down" - (interactive) - (scroll-up) - (novel--cursor-pos)) - -;; invert everything, reverse it when called again -(defun novel-invert() - "Invert foreground and background colors" - (interactive) - (invert-face 'default) - (set-face-attribute 'fringe nil :inverse-video novel--invert-state) - (setq novel--invert-state (not novel--invert-state)) ;; cycle - (when novel-feedback - (message "inverted colors"))) - -(defun novel-incr-margins() - "Increment window margins" - (interactive) - (setq novel--cur-margin (if (= novel--cur-margin novel--max-margin) - novel--cur-margin - (+ novel--cur-margin 1))) - (novel--set-margins)) - -(defun novel-decr-margins() - "Decrement window margins" - (interactive) - (setq novel--cur-margin (if (= novel--cur-margin 0) 0 (- novel--cur-margin 1))) - (novel--set-margins)) - -(defun novel-incr-font-size () - "Increase font size" - (interactive) - (text-scale-increase 0.5) - (when novel-feedback - (message "increased font size"))) - -(defun novel-decr-font-size () - "Decrease font size" - (interactive) - (text-scale-increase -0.5) - (when novel-feedback - (message "decreased font size"))) - -(defun novel-toggle() - "Toggle reading mode" - (interactive) - (if (null (get this-command 'state-on-p)) - ;; enable, primary novel mode setup - (progn - (novel--backup-states) - (run-hooks 'novel-mode-pre-start-hook) - - (setq novel--max-margin (/ (- (window-body-width) 40) 2)) - (if (not novel-default-margin) - (setq novel-default-margin (/ (- (window-body-width) fill-column) 3))) - (setq novel--cur-margin novel-default-margin) - - (setq scroll-step 1 ; scroll linewise - scroll-conservatively 10000 - cursor-type nil ; no cursor - line-spacing 3 ; more distance between lines - mode-line-format nil ; no modeline - visual-line-mode t ; no wrap marker on fringe - word-wrap t - ) - - (delete-other-windows) ; There can be only one, McLeod. - (novel--set-margins) - - (variable-pitch-mode 1) ; enable variable width font - (text-scale-increase 2) ; larger font size - (put this-command 'state-on-p t) ; remeber current state - - (menu-bar-mode -1) ; disable widgets - (tool-bar-mode -1) - (scroll-bar-mode 0) - (set-fringe-mode 0) ; no fringe - - (novel--remap-self-insert) ; disable all keys but ours - - (run-hooks 'novel-mode-post-start-hook) - ) - - ;; disable, restore everything back to normal - (progn - (run-hooks 'novel-mode-pre-stop-hook) - - (setq scroll-step 0 - scroll-conservatively 0 - line-spacing nil - cursor-type novel--ct - mode-line-format novel--mlf - visual-line-mode novel--vlm - word-wrap novel--ww - menu-bar-mode novel--mbm - tool-bar-mode novel--tbm - scroll-bar-mode novel--sbm) - - (set-fringe-mode 1) - (set-window-margins nil 0 0) - (variable-pitch-mode 0) - (text-scale-increase -2) - (put this-command 'state-on-p nil) - (novel--reset-remap-self-insert) - - (if (not novel--invert-state) - (novel-invert)) - - (run-hooks 'novel-mode-post-stop-hook) - )) - (redraw-frame (selected-frame))) - -(defun novel-help() - "Display help" - (interactive) - (message "Available commands in novel mode: - n scroll one page down - p scroll one page up - scroll one line down - scroll one line up - mousewheel scroll linewise up or down - SPC scroll one page down - increase margins, makes visible text narrower - decrease margins, makes visible text wider - + increase font size - - decrease font size - i invert video display - q quit novel mode - ? or h display key mapping -")) - -;;;; Interface - -;;;###autoload -(define-minor-mode novel-mode "screen reader mode" - :lighter " V" - :group 'novel-mode - :keymap (let ((map (make-sparse-keymap))) - (define-key map (kbd "") 'novel-up) - (define-key map (kbd "") 'novel-down) - (define-key map (kbd "") 'novel-up) - (define-key map (kbd "") 'novel-down) - - (define-key map (kbd "SPC") 'novel-page-down) - (define-key map (kbd "") 'novel-page-down) - (define-key map (kbd "") 'novel-page-up) - (define-key map (kbd "n") 'novel-page-down) - (define-key map (kbd "p") 'novel-page-up) - - (define-key map (kbd "") 'novel-decr-margins) - (define-key map (kbd "") 'novel-incr-margins) - - (define-key map (kbd "i") 'novel-invert) - (define-key map (kbd "+") 'novel-incr-font-size) - (define-key map (kbd "-") 'novel-decr-font-size) - (define-key map (kbd "q") 'novel-mode) - - (define-key map (kbd "h") 'novel-help) - (define-key map (kbd "?") 'novel-help) - map) - (novel-toggle) - ) - - -(provide 'novel-mode) - -;;; novel-mode.el ends here