;;; esv.el --- read the Bible -*- lexical-binding:t -*- ;; Copyright (C) 2024 Jeremy Baxter ;; Author: Jeremy Baxter ;; Maintainer: Jeremy Baxter ;; Created: May 2024 ;; Keywords: bible ;; This file is not part of GNU Emacs. ;; esv.el 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. ;; ;; esv.el 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 esv.el. If not, see . ;;; Commentary: ;; esv.el provides `esv', a command for fetching a given passage of ;; the ESV Bible. The majority of the work is done by the esv command ;; line tool; esv.el just presents the text nicely in an Emacs buffer ;; for a pleasurable viewing experience. ;; ;; If you do not already have esv, find it on its website: ;; https://sr.ht/~jeremy/esv ;;; Code: (defgroup esv nil "Read the Bible." :prefix "esv-" :group 'applications) (defcustom esv-close-existing-buffers nil "Whether to close an existing `esv' buffer if one already exists." :type 'boolean) (defcustom esv-columns 72 "Length of each line output by `esv'." :type 'natnum) (defcustom esv-mode-hook nil "Hook run after entering `esv-mode'." :type 'hook) (defcustom esv-process "esv" "Name of the process created by `esv'." :type 'string) (defcustom esv-program "esv" "Path to or name of the program started by `esv'." :type 'string) (defvar esv-arguments '() "List of additional arguments passed to `esv-program'.") (define-derived-mode esv-mode text-mode "ESV-Bible" "Major mode used for reading the Bible with `esv'." :group 'esv (read-only-mode)) (defun esv (passage) "Fetch the Bible passage identified by BOOK and VERSES. The result will be redirected to a buffer named after the passage. Requires the esv command line tool to be in the system's PATH. esv can be acquired at ." (interactive "MPassage: ") (let* ((slices (split-string passage)) (verses (car (last slices))) (book (mapconcat #'(lambda (e) e) (take (1- (length slices)) slices) " ")) (buffer (concat book " " verses)) (arg-list (append esv-arguments (list (format "-l%d" esv-columns)) (list book) (list verses)))) (catch 'buffer-exists (when (get-buffer buffer) (unless esv-close-existing-buffers (message "Buffer `%s' already exists" buffer) (throw 'buffer-exists nil)) (kill-buffer buffer))) (apply #'call-process esv-program nil buffer t arg-list) (display-buffer buffer) (with-current-buffer buffer (esv-mode) (goto-char (point-min))) (set-window-start (get-buffer-window buffer) (point-min))) t) (provide 'esv) ;;; esv.el ends here