Browse Source

Fix various formatting issues introduced by previous changes

- Fix line breaks
- Don't delete part of the verse when formatting the verse number
- Try to eliminate spurious spaces
Fred Gilham 3 months ago
parent
commit
05180a4d4f
1 changed files with 264 additions and 234 deletions
  1. 264 234
      bible-mode.el

+ 264 - 234
bible-mode.el

@@ -1,10 +1,9 @@
 ;;;; -*- mode: EMACS-LISP; lexical-binding: t -*-
 ;;
 ;; bible-mode.el --- A browsing interface for the SWORD Project's Diatheke CLI
-;; Time-stamp: <2024-09-27 08:54:19 fred>
 
 ;; Author: Zacalot
-;; Fixes and modifications by Fred Gilham
+;; Substantial fixes and modifications by Fred Gilham
 ;; Url: https://gitbot.homedns.org/fred/bible-mode
 ;; Forked from
 ;; Url: https://github.com/Zacalot/bible-mode
@@ -58,15 +57,14 @@
 
 
 ;;;
-;;; bm- is used as shorthand (see Local Variables) for bible-mode-
+;;; "bm-" is used as shorthand (see Local Variables) for "bible-mode-"
+;;; Names of the form "bm--" are intended to be "unexported".
 
 ;;; Code:
 
 ;;;; Requirements
 ;;; XXX FMG there are just a few constructs that use this; use elisp versions instead.
-;; cl-do* cl-fresh-line
-(require 'cl-lib) 
-;; (require 'bidi)
+;;(require 'cl-lib) 
 (require 'dom)
 (require 'shr)
 
@@ -99,7 +97,7 @@
 
 
 (defcustom bm-greek-lexicon
-  "MLStrong"
+  "AbbottSmithStrongs"
   "Lexicon used for displaying definitions of Greek words using Strong's codes."
   :type '(string :tag "Lexicon module (e.g. \"StrongsRealGreek\").")
   :local nil
@@ -107,17 +105,19 @@
 
 
 (defcustom bm-use-index-for-lexicon nil
-  "Some lexicons are accessed by lemmas rather than Strong's numbers. Use
-an index to look up lemmas from Strong's numbers so these lexicons can
+  "Some lexicons are accessed by lemmas rather than Strong's numbers. 
+Use an index to look up lemmas from Strong's numbers so these lexicons can
 be used. Examples of this type of lexicon are AbbottSmith and
-LiddellScott. XXX LiddellScott currently doesn't work."
+LiddellScott. XXX LiddellScott currently doesn't work. XXX AbbottSmithStrongs
+now has the complete entries instead of just links."
+  
   :type 'boolean
   :local nil
   :group 'bible-mode)
 
 (defcustom bm-lexicon-index "AbbottSmithStrongs"
-  "A module that consists of an index mapping Strong's numbers to Greek
-lemmas. The code is written to use the entries in AbbottSmithStrongs
+  "A module that consists of an index mapping Strong's numbers to Greek lemmas. 
+The code is written to use the entries in AbbottSmithStrongs
 which are of the form
 
 <strong's number>: @LINK <greek lemma>"
@@ -162,11 +162,19 @@ which are of the form
   :local t
   :group 'bible-mode)
 
-;;; defvars
+(defcustom bm-show-diatheke-exec
+  t
+  "Show the arguments by which diatheke is executed."
+  :type 'boolean
+  :local nil
+  :group 'bible-mod)
+
+;;; variable defs
 
 ;;(defvar bm-verse-regexp "([\d ]*[a-zA-Z]+( \d*:\d*)?)(( - )| )?(((\d* )?[a-zA-Z]+ )?\d*([:-]+\d*)?)")
 ;; (defvar bm-verse-regexp "/(\d*)\s*([a-z]+)\s*(\d+)(?::(\d+))?(\s*-\s*(\d+)(?:\s*([a-z]+)\s*(\d+))?(?::(\d+))?)?/i")
-(defvar bm-verse-regexp "\\(I?I \\)*[a-zA-Z]* [0-9]*[:.][0-9]*")
+(defconst bm-verse-regexp "\\(I \\|II \\|III \\)??[a-zA-Z]+?[ \t\n][0-9]+[:][0-9]+")
+
 
 (defvar bm-modules (lazy-completion-table bm-modules bm--list-biblical-modules))
 
@@ -175,54 +183,44 @@ which are of the form
   '(;; Old Testament
     ("Genesis"		. 50)	("Exodus"		. 40)	("Leviticus"		. 27)	("Numbers"		. 36)
     ("Deuteronomy"	. 34)	("Joshua"		. 24)	("Judges"		. 21)	("Ruth"			. 4)
-    ("I Samuel"		. 31)   ("1 Samuel"		. 31)	("II Samuel"		. 24)   ("2 Samuel"		. 24)
-    ("I Kings"		. 22)   ("2 Kings"		. 22)	("II Kings"		. 25)   ("2 Kings"		. 25)
-    ("I Chronicles"	. 29)   ("1 Chronicles"	        . 29)	("II Chronicles"	. 36)   ("2 Chronicles"	        . 36)
-    ("Ezra"		. 10)	("Nehemiah"		. 13)   ("Esther" 		. 10)	("Job"			. 42)
-    ("Psalms"		. 150)	("Proverbs"		. 31)   ("Ecclesiastes"		. 12)	("Song of Solomon"	. 8)
-    ("Isaiah"		. 66)	("Jeremiah"		. 52)   ("Lamentations"		. 5)	("Ezekiel"		. 48)
-    ("Daniel"		. 12)	("Hosea"		. 14)   ("Joel"			. 3)	("Amos"			. 9)
-    ("Obadiah"		. 1)	("Jonah"		. 4)    ("Micah"		. 7)	("Nahum"		. 3)
-    ("Habakkuk"		. 3)	("Zephaniah"		. 3)    ("Haggai"		. 2)	("Zechariah"		. 14)
-    ("Malachi"		. 4)
+    ("I Samuel"		. 31)	("II Samuel"		. 24)	("I Kings"		. 22)	("II Kings"		. 25)
+    ("I Chronicles"	. 29)	("II Chronicles"	. 36)	("Ezra"			. 10)	("Nehemiah"		. 13)
+    ("Esther" 		. 10)	("Job"			. 42)	("Psalms"		. 150)	("Proverbs"		. 31)
+    ("Ecclesiastes"	. 12)	("Song of Solomon"	. 8)	("Isaiah"		. 66)	("Jeremiah"		. 52)
+    ("Lamentations"	. 5)	("Ezekiel"		. 48)	("Daniel"		. 12)	("Hosea"		. 14)
+    ("Joel"		. 3)	("Amos"			. 9)	("Obadiah"		. 1)	("Jonah"		. 4)
+    ("Micah"		. 7)	("Nahum"		. 3)	("Habakkuk"		. 3)	("Zephaniah"		. 3)
+    ("Haggai"		. 2)	("Zechariah"		. 14)	("Malachi"		. 4)
     ;; New Testament
     ("Matthew"		. 28)	("Mark"			. 16)	("Luke"			. 24)	("John"			. 21)
-    ("Acts"		. 28)	("Romans"		. 16)	("I Corinthians"	. 16)	("1 Corinthians"	. 16)
-    ("II Corinthians" 	. 13)	("2 Corinthians" 	. 13)   ("Galatians"		. 6)	("Ephesians"		. 6)
-    ("Philippians"	. 4)	("Colossians"		. 4)    ("I Thessalonians"	. 5)	("1 Thessalonians"	. 5)
-    ("II Thessalonians"	. 3)	("2 Thessalonians"	. 3)	("I Timothy"		. 6)	("I Timothy"		. 6)
-    ("II Timothy"	. 4)	("2 Timothy"		. 4)    ("Titus"		. 3)	("Philemon"		. 1)
-    ("Hebrews"		. 13)	("James"		. 5)    ("I Peter"		. 5)	("1 Peter"		. 5)
-    ("II Peter"		. 3)	("2 Peter"		. 3)	("I John"		. 5)	("1 John"		. 5)
-    ("II John"		. 1)	("2 John"		. 1)    ("III John"		. 1)	("3 John"		. 1)
-    ("Jude"		. 1)	("Revelation of John"	. 22))
+    ("Acts"		. 28)	("Romans"		. 16)	("I Corinthians"	. 16)	("II Corinthians" 	. 13)
+    ("Galatians"	. 6)	("Ephesians"		. 6)	("Philippians"		. 4)	("Colossians"		. 4)
+    ("I Thessalonians"	. 5)	("II Thessalonians"	. 3)	("I Timothy"		. 6)	("II Timothy"		. 4)
+    ("Titus"		. 3)	("Philemon"		. 1)	("Hebrews"		. 13)	("James"		. 5)
+    ("I Peter"		. 5)	("II Peter"		. 3)	("I John"		. 5)	("II John"		. 1)
+    ("III John"		. 1)    ("Jude"			. 1)	("Revelation of John"	. 22))
   "A-list of name / chapter count for Bible books.")
 
 (defvar bm-book-name-abbreviations-alist
   '(;; Old Testament
-    ("Ge"     . "Genesis")         ("Ex"    . "Exodus")           ("Le"     . "Leviticus")     ("Nu"    . "Numbers")
-    ("De"     . "Deuteronomy")     ("Js"    . "Joshua")           ("Jg"     . "Judges")        ("Ru"    . "Ruth")
-    ("I Sa"   . "I Samuel")        ("1 Sa"  . "I Samuel")         ("II Sa"  . "II Samuel")     ("2 Sa"  . "II Samuel")
-    ("I Ki"   . "I Kings")         ("2 Ki"  . "I Kings")          ("II Ki"  . "II Kings")      ("2 Ki"  . "II Kings")
-    ("I Ch"   . "I Chronicles")    ("1 Ch"  . "I Chronicles")     ("II Ch"  . "II Chronicles") ("2 Ch"  . "II Chronicles")
-    ("Ezr"    . "Ezra")            ("Ne"    . "Nehemiah")
-    ("Es"     . "Esther")          ("Jb"    . "Job")              ("Ps"     . "Psalms")        ("Pr"    . "Proverbs")
-    ("Ec"     . "Ecclesiastes")    ("So"    . "Song of Solomon")  ("Is"     . "Isaiah")        ("Je"    . "Jeremiah")
-    ("La"     . "Lamentations")    ("Ez"    . "Ezekiel")          ("Da"     . "Daniel")        ("Ho"    . "Hosea")
-    ("Joe"    . "Joel")	           ("Am"    . "Amos")             ("Ob"     . "Obadiah")       ("Jon"   . "Jonah")
-    ("Mi"     . "Micah")           ("Na"    . "Nahum")            ("Ha"     . "Habakkuk")      ("Zep"   . "Zephaniah")
-    ("Hag"    . "Haggai")          ("Ze"    . "Zechariah")        ("Mal"    . "Malachi")
+    ("Ge"     . "Genesis")         ("Ex"    . "Exodus")           ("Le"   . "Leviticus")     ("Nu"    . "Numbers")
+    ("De"     . "Deuteronomy")     ("Js"    . "Joshua")           ("Jg"   . "Judges")        ("Ru"    . "Ruth")
+    ("I Sa"   . "I Samuel")        ("II Sa" . "II Samuel")        ("I Ki" . "I Kings")       ("II Ki" . "II Kings") 
+    ("I Ch"   . "I Chronicles")    ("II Ch" . "II Chronicles")    ("Ezr"  . "Ezra")          ("Ne"    . "Nehemiah")
+    ("Es"     . "Esther")          ("Jb"    . "Job")              ("Ps"   . "Psalms")        ("Pr"    . "Proverbs")
+    ("Ec"     . "Ecclesiastes")    ("So"    . "Song of Solomon")  ("Is"   . "Isaiah")        ("Je"    . "Jeremiah")
+    ("La"     . "Lamentations")    ("Ez"    . "Ezekiel")          ("Da"   . "Daniel")        ("Ho"    . "Hosea") 
+    ("Joe"    . "Joel")	           ("Am"    . "Amos")             ("Ob"   . "Obadiah")       ("Jon"   . "Jonah")
+    ("Mi"     . "Micah")           ("Na"    . "Nahum")            ("Ha"   . "Habakkuk")      ("Zep"   . "Zephaniah")     
+    ("Hag"    . "Haggai")          ("Ze"    . "Zechariah")        ("Mal"  . "Malachi")
     ;; New Testament
-    ("Mt"     . "Matthew")          ("Mk"    . "Mark")             ("Lk"     . "Luke")            ("Jo"    . "John")
-    ("Ac"     . "Acts")             ("Ro"    . "Romans")           ("I Co"   . "I Corinthians")   ("1 Co"  . "I Corinthians")
-    ("II Co"  . "II Corinthians")   ("2 Co"  . "II Corinthians")   ("Ga"     . "Galatians")       ("Eph"   . "Ephesians")
-    ("Phl"    . "Philippians")      ("Col"   . "Colossians")       ("I Th"   . "I Thessalonians") ("1 Th"  . "I Thessalonians")
-    ("II Th"  . "II Thessalonians") ("2 Th"  . "II Thessalonians") ("I Ti"   . "I Timothy")       ("I Ti"  . "I Timothy")
-    ("II Ti"  . "II Timothy")       ("2 Ti"  . "II Timothy")       ("Tit"    . "Titus")           ("Phm"   . "Philemon")
-    ("He"     . "Hebrews")          ("Ja"    . "James")            ("I Pe"   . "I Peter")         ("1 Pe"  . "I Peter")
-    ("II Pe"  . "II Peter")         ("2 Pe"  . "II Peter")	   ("I Jo"   . "I John")          ("1 Jo"  . "I John")
-    ("II Jo"  . "II John")          ("2 Jo"  . "II John")          ("III Jo" . "III John")        ("3 Jo"  . "III John")
-    ("Ju"     . "Jude")             ("Re"    . "Revelation of John"))
+    ("Mt"     . "Matthew")         ("Mk"    . "Mark")             ("Lk"   . "Luke")          ("Jo"    . "John")
+    ("Ac"     . "Acts")            ("Ro"    . "Romans")           ("I Co" . "I Corinthians") ("II Co" . "II Corinthians")
+    ("Ga"     . "Galatians")       ("Eph"   . "Ephesians")	  ("Phl"  . "Philippians")   ("Col"   . "Colossians")
+    ("I Th"   . "I Thessalonians") ("II Th" . "II Thessalonians") ("I Ti" . "I Timothy")     ("II Ti" . "II Timothy")
+    ("Tit"    . "Titus")           ("Phm"   . "Philemon")	  ("He"   . "Hebrews")       ("Ja"    . "James")
+    ("I Pe"   . "I Peter")         ("II Pe" . "II Peter")	  ("I Jo" . "I John")        ("II Jo" . "II John")
+    ("III Jo" . "III John")        ("Ju"    . "Jude")             ("Re"   . "Revelation of John"))
   "A-list of abbreviations for Bible books.")
 
 ;;;; Book / chapter
@@ -236,7 +234,7 @@ which are of the form
 (defvar-local bm-current-chapter 1
   "Current book chapter number.")
 
-(defvar-local bm-search-query nil 
+(defvar-local bm-query nil 
   "Search query associated with the buffer.")
 
 (defvar-local bm-search-mode "phrase"
@@ -262,6 +260,16 @@ which are of the form
 	    [menu-bar bible-mode toggle-debug]
 	    '("Toggle debug-on-error" . toggle-debug-on-error))
 
+
+(defun bm-toggle-display-diatheke ()
+  "Toggle XML display."
+  (interactive)
+  (setq bm-show-diatheke-exec (not bm-show-diatheke-exec)))
+
+(define-key bm-map
+	    [menu-bar bible-mode display-diatheke]
+	    '("Toggle diatheke display" . bm-toggle-display-diatheke))
+
 (defun bm-toggle-display-xml ()
   "Toggle XML display."
   (interactive)
@@ -315,6 +323,7 @@ which are of the form
 ;;;;; Misc
 (define-key bm-map "m" 'bm-select-module)
 (define-key bm-map "w" 'bm-toggle-word-study)
+(define-key bm-map "r" 'bm-toggle-red-letter)
 
 (define-key bm-map "x" 'bm-split-display)
 (define-key bm-map
@@ -398,7 +407,7 @@ which are of the form
 	    [menu-bar bible-mode select-biblical-text]
 	    '("Select Module" . bm-display-available-modules))
 
-(defun bm-display-greek ()
+(defun bm--display-greek ()
   "This command is run by clicking on text, not directly by the user."
   (interactive)
   (let ((item (car (split-string (get-text-property (point) 'strong)))))
@@ -406,10 +415,10 @@ which are of the form
     (bible-term-greek (replace-regexp-in-string "strong:G" "" item))))
 	      
 (defconst bm-greek-keymap (make-sparse-keymap))
-(define-key bm-greek-keymap (kbd "RET") 'bm-display-greek)
-(define-key bm-greek-keymap [mouse-1] 'bm-display-greek)
+(define-key bm-greek-keymap (kbd "RET") 'bm--display-greek)
+(define-key bm-greek-keymap [mouse-1] 'bm--display-greek)
 
-(defun bm-display-hebrew () 
+(defun bm--display-hebrew () 
   "This command is run by clicking on text, not directly by the user."
   (interactive)
   (let ((item (car (split-string (get-text-property (point) 'strong)))))
@@ -417,8 +426,8 @@ which are of the form
     (bible-term-hebrew (replace-regexp-in-string "strong:H" "" item))))
 
 (defconst bm-hebrew-keymap (make-sparse-keymap))
-(define-key bm-hebrew-keymap (kbd "RET") 'bm-display-hebrew)
-(define-key bm-hebrew-keymap [mouse-1] 'bm-display-hebrew)
+(define-key bm-hebrew-keymap (kbd "RET") 'bm--display-hebrew)
+(define-key bm-hebrew-keymap [mouse-1] 'bm--display-hebrew)
 
 (defconst bm-lemma-keymap (make-sparse-keymap))
 (define-key bm-lemma-keymap (kbd "RET")
@@ -473,7 +482,8 @@ which are of the form
   (font-lock-mode t)
   (use-local-map bible-term-greek-mode-map)
   (setq buffer-read-only t)
-  (visual-line-mode t))
+  (visual-line-mode t)
+)
 
 (define-derived-mode module-select-mode special-mode "Select Text Module"
   (buffer-disable-undo)
@@ -487,7 +497,10 @@ which are of the form
 
 ;;;###autoload
 (defun bible-open (&optional book-name chapter verse)
-  "Creates and opens a `bible-mode' buffer"
+  "Create and open a `bible-mode' buffer. 
+Arguments BOOK-NAME, CHAPTER and VERSE, when supplied, give the starting
+verse reference for the buffer. If no optional arguments are supplied, 
+Genesis 1:1 is used."
   (interactive)
   (let ((buf (get-buffer-create (generate-new-buffer-name (concat "*bible*")))))
     (set-buffer buf)
@@ -497,7 +510,7 @@ which are of the form
 
 ;;;###autoload
 (defun bm-next-chapter ()
-  "Pages to the next chapter for the active `bible-mode' buffer."
+  "Page to the next chapter for the active `bible-mode' buffer."
   (interactive)
   (let* ((book-chapters (cdr bm-current-book))
 	 (chapter (min book-chapters (+ bm-current-chapter 1))))
@@ -505,28 +518,24 @@ which are of the form
 
 ;;;###autoload
 (defun bm-previous-chapter ()
-  "Pages to the previous chapter for the active `bible-mode' buffer."
+  "Page to the previous chapter for the active `bible-mode' buffer."
   (interactive)
   (bm--set-location bm-current-book (max 1 (- bm-current-chapter 1))))
 
 
 (defun bm-next-word ()
-  "Moves forward a word, taking into account the relevant text 
-properties."
+  "Move forward a word, taking into account the relevant text properties."
   (interactive)
   (unless (eobp)
-    (let ((plist (text-properties-at (point)))
-          (next-change (text-property-search-forward 'strong nil nil t)))
+    (let ((next-change (text-property-search-forward 'strong nil nil t)))
       (when next-change
 	(goto-char (1- (prop-match-end next-change)))))))
 
 (defun bm-previous-word ()
-  "Moves forward a word, taking into account the relevant text 
-properties."
+  "Move back a word, taking into account the relevant text properties."
   (interactive)
   (unless (bobp)
-    (let ((plist (text-properties-at (point)))
-          (previous-change (text-property-search-backward 'strong)))
+    (let ((previous-change (text-property-search-backward 'strong)))
       (when previous-change
 	(goto-char (prop-match-beginning previous-change))))))
 
@@ -534,8 +543,7 @@ properties."
 
 ;;;###autoload
 (defun bm-select-book ()
-  "Queries user to select a new book and chapter for the current
-`bible-mode' buffer."
+  "Ask user for a new book and chapter for the current `bible-mode' buffer."
   (interactive)
   (let* ((completion-ignore-case t)
 	 (book-data (assoc (completing-read "Book: " bm-books nil t) bm-books))
@@ -548,7 +556,7 @@ properties."
 
 ;;;###autoload
 (defun bm-select-chapter ()
-  "Queries user to select a new chapter for the current `bible-mode' buffer."
+  "Ask user for a new chapter for the current `bible-mode' buffer."
   (interactive)
   (let* ((book-chapters (cdr bm-current-book))
 	 (chapter (string-to-number (completing-read "Chapter: " (bm--list-number-range 1 book-chapters) nil t))))
@@ -557,7 +565,7 @@ properties."
 
 ;;;###autoload
 (defun bm-select-module ()
-  "Queries user to select a new reading module for the current `bible-mode' buffer."
+  "Ask user for a new text module for the current `bible-mode' buffer."
   (interactive)
   (let ((module (completing-read "Module: " bm-modules)))
     (setq-local bm-module module)
@@ -565,16 +573,24 @@ properties."
 
 ;;;###autoload
 (defun bm-toggle-word-study()
-  "Toggles the inclusion of word study for the active `bible-mode' buffer."
+  "Toggle the inclusion of word study for the active `bible-mode' buffer."
   (interactive)
   (setq bm-word-study-enabled (not bm-word-study-enabled))
   (if (equal major-mode 'bible-search-mode)
       (bm--display-search bm-search-query bm-search-mode bm-module)
     (bm--display)))
 
+(defun bm-toggle-red-letter()
+  "Toggle red letter mode for the active `bible-mode' buffer."
+  (interactive)
+  (setq bm-red-letter-enabled (not bm-red-letter-enabled))
+  (if (equal major-mode 'bible-search-mode)
+      (bm--display-search bm-search-query bm-search-mode bm-module)
+    (bm--display)))
+
 ;;;###autoload
 (defun bm-split-display ()
-  "Copies the active `bible-mode' buffer into a new buffer in another window."
+  "Copy the active `bible-mode' buffer into a new buffer in another window."
   (interactive)
   (split-window-right)
   (balance-windows)
@@ -594,8 +610,8 @@ search."
 
 ;;;###autoload
 (defun bible-search-mode-follow-verse ()
-  "Follows the hovered verse in a `bible-search-mode' buffer,
-creating a new `bible-mode' buffer positioned at the specified verse."
+  "Follow the hovered verse in a `bible-search-mode' buffer.
+Create a new `bible-mode' buffer positioned at the selected verse."
   (interactive)
   (let* ((text (thing-at-point 'line t))
          book
@@ -611,10 +627,10 @@ creating a new `bible-mode' buffer positioned at the specified verse."
     (bible-open (string-trim book) (string-to-number chapter) (string-to-number verse))))
 
 (defun bible-search-mode-follow-xref ()
-  "Follows the hovered verse in a `bible-search-mode' buffer,
-creating a new `bible-mode' buffer positioned at the specified verse.
-N.B. We use the default module to avoid opening cans of worms regarding
-OT/NT etc."
+  "Follow the hovered verse in a bible term buffer.
+Create a new `bible-mode' buffer positioned at the specified verse.
+XXX We use the current module to avoid opening cans of worms regarding
+OT/NT etc. If that module doesn't have that verse...???"
   (interactive)
   (let* ((xref (get-text-property (point) 'xref))
 	 (verse-ref (string-split xref))
@@ -639,19 +655,19 @@ OT/NT etc."
 
 ;;;###autoload
 (defun bible-term-hebrew (term)
-  "Queries user for a Strong's Hebrew Lexicon term."
+  "Query user for a Strong's Hebrew Lexicon TERM."
   (interactive "sTerm: ")
   (bm--open-term-hebrew term))
 
 ;;;###autoload
 (defun bible-term-greek (term)
-  "Queries user for a Strong's Greek Lexicon term."
+  "Query user for a Strong's Greek Lexicon TERM."
   (interactive "sTerm: ")
   (bm--open-term-greek term))
 
 ;;;###autoload
 (defun bible-insert ()
-  "Queries user to select a verse for insertion into the current buffer."
+  "Query user to select a verse for insertion into the current buffer."
   (interactive)
   (let* ((completion-ignore-case t)
 	 (book-data (assoc (completing-read "Book: " bm-books nil t) bm-books))
@@ -666,28 +682,31 @@ OT/NT etc."
 
 ;;;;; Support
 
+
+(defconst diatheke-filter-options " avlnmw")
 ;;;
-;;; XXX I've magled this in an ad-hoc manner. It needs to be
+;;; XXX I've mangled this in an ad-hoc manner. It needs to be
 ;;; re-written so it is clearer (and correct, for that matter).
 (defun bm--exec-diatheke (query &optional filter format searchtype module)
-  "Executes `diatheke' with specified query options, returning the output."
+  "Execute `diatheke' with specified QUERY options, returning the output."
   (let ((module (or module bm-module)))
     (with-temp-buffer
       (let ((args (list "diatheke" nil (current-buffer) t "-b" module)))
 	(if filter
-	    (setq filter (concat filter " avlnmws"))
-	    (setq filter "avlmnws"))
+	    (setq filter (concat filter diatheke-filter-options))
+	    (setq filter diatheke-filter-options))
 	(when filter (setq args (append args (list "-o" filter))))
 	(when searchtype
 	  (setq args (append args (list "-s" (pcase searchtype ("lucene" "lucene") ("phrase" "phrase"))))))
 	(setq args (append args (list "-f" (pcase format ("plain" "plain") (_ "internal")) "-k" query)))
-	(message "%s" args)
+	(when bm-show-diatheke-exec
+	  (message "%s" args))
 	(apply 'call-process args))
       (buffer-string))))
 
 (defvar-local bm-chapter-title nil
-  "Document text at start of chapter, mostly in Psalms, 
-like `Of David' or the like.")
+  "Text preceding start of chapter.
+Mostly in Psalms, like `Of David' or the like.")
 
 
 ;;;
@@ -712,10 +731,12 @@ like `Of David' or the like.")
 
 ;;; Use HTMLHREF format with diatheke, post-process to render html.
 (defun bm--morph-query (query module)
-  "Executes `diatheke' to do morph query, renders HTML, returns string.
-Does some tweaking specific to morphology."
+  "Execute `diatheke' to do morph QUERY, using MODULE.
+Render HTML, return string. Do some tweaking specific to morphology."
   (with-temp-buffer
     (let ((args (list "diatheke" nil (current-buffer) t "-b" module "-o" "m" "-f" "HTMLHREF" "-k" query)))
+      (when bm-show-diatheke-exec
+	(message "%s" args))
       (apply 'call-process args)
       (shr-render-region (point-min) (point-max))
       (format-replace-strings 
@@ -727,12 +748,13 @@ Does some tweaking specific to morphology."
 
 ;;; Use "plain" format with diatheke.
 (defun bm--lex-query (query module)
-  "Executes `diatheke' for query, plain format, returns string."
+  "Execute `diatheke' for QUERY, using MODULE.
+Plain format, returns string."
   ;; Get rid of query ID at front of string: ?????:
   (bm--exec-diatheke query nil "plain" nil module))
 
 (defun bm--lookup-lemma-index (key)
-  "Given a strong's number, return the Greek lemma from lemma index."
+  "Given a strong's number KEY, return the Greek lemma from lemma index."
   (or (gethash key lemma-index-hash)
       (puthash key 
 	       (string-trim 
@@ -747,8 +769,8 @@ Does some tweaking specific to morphology."
 ;;; cross-references and/or Strong's references.
 	   
 (defun bm--process-href ()
-  "This fixes the XML so cross-references are in the right format. These
-cross-references get processed later when the term is displayed.
+  "Fix the XML so cross-references are in the right format. 
+These cross-references get processed later when the term is displayed.
 
 First, find the links put in by diatheke's HTMLHREF output format.
 Replace the links with verse references that get changed to clickable
@@ -765,7 +787,7 @@ them to the <bookname> <chapter>:<verse> format."
 
       ;; Delete original link.
       (replace-match "" nil nil)
-    
+      
       ;; Get the verse reference from the string we saved. Put it in
       ;; good format, then insert it into buffer where href was.
 
@@ -784,33 +806,36 @@ them to the <bookname> <chapter>:<verse> format."
 	  (when (setq period (cl-search "." verse-ref-string))
 	    (aset verse-ref-string period ?:))
 
-	  ;; Handle leading 1, 2 or 3 (i.e. 3 John etc.)
-	  (when (= (aref verse-ref-string 0) ?1)
-	    (setq verse-ref-string (concat "I" (substring verse-ref-string 1))))
-	  (when (= (aref verse-ref-string 0) ?2)
-	    (setq verse-ref-string (concat "II" (substring verse-ref-string 1))))
-	  (when (= (aref verse-ref-string 0) ?3)
-	    (setq verse-ref-string (concat "III" (substring verse-ref-string 1))))
-      
+	  ;; Replace numbers (1, 2 or 3) with roman numerals (I, II, III) XXX Fix?
+	  (pcase (aref verse-ref-string 0)
+	    (?1 (setq verse-ref-string (concat "I" (substring verse-ref-string 1))))
+	    (?2 (setq verse-ref-string (concat "II" (substring verse-ref-string 1))))
+	    (?3 (setq verse-ref-string (concat "III" (substring verse-ref-string 1)))))
+
 	  (set-text-properties 0 verse-ref-length nil verse-ref-string) ; Clear unwanted properties (if any)
 	  (insert verse-ref-string))))))
 
 (defun bm--lookup-greek-def (key)
-  "Executes `diatheke' to do query, massages output so verse cross
-references are usable. Returns string. We use HTMLHREF format output
-because it may have verse references as HTML links, depending on the
-lexicon module."
+  "Execute `diatheke' to do query on KEY.
+Massage output so verse cross references are usable. Returns string.
+We use HTMLHREF format output because it may have verse references
+as HTML links, depending on the lexicon module."
 
   (with-temp-buffer
     (let ((args (list "diatheke" nil (current-buffer) t "-b" bm-greek-lexicon "-o" "m" "-f" "HTMLHREF" "-k" key)))
+      ;; XXX Change to OSIS? Need to parse OSIS-style references.
+;;;    (let ((args (list "diatheke" nil (current-buffer) t "-b" bm-greek-lexicon "-o" "m" "-f" "OSIS" "-k" key)))
+      (when bm-show-diatheke-exec
+	(message "%s" args))
       (apply 'call-process args)
       (bm--process-href)    ; Clean up XML so xrefs can work after rendering.
-      (shr-render-region (point-min) (point-max)))
-    (buffer-string)))
+      (shr-render-region (point-min) (point-max))
+      (buffer-string))))
 
 (defun bm--lookup-lex-greek-indexed (key)
-  "If the lexicon module uses Greek lemmas as lookup keys, get the lemmas
-from the Strong's number. Then look up the definition."
+  "Get Greek lemma using Strong's number KEY.
+Then look up the definition of that lemma. Used when two-stage 
+lexical definition is set for a particular lexicon."
   (let ((lemma-entry (bm--lookup-lemma-index key))) ; Get lemma from Strong's number
     (when lemma-entry
       (let ((lemma (caddr (split-string lemma-entry " "))))
@@ -818,46 +843,38 @@ from the Strong's number. Then look up the definition."
 
 
 (defun bm--lookup-lex-greek (key)
-  "Lookup lexical definition using Strong's number as follows:
+  "Lookup lexical definition using Strong's number KEY.
 1. Check hash table first. If entry found, return.
 2. Otherwise, if a lexicon is accessed by lemmas, do lookup using index method.
 3. Otherwise just use the Strong's number method."
   (or (gethash key greek-hash)
-      (puthash key 
+      (puthash key
 	       (if bm-use-index-for-lexicon
 		   (bm--lookup-lex-greek-indexed key)
 		 (bm--lookup-greek-def key))
 	       greek-hash)))
 
 (defun bm--lookup-strongs-greek (window object pos)
-  "Look up Greek lexical string from Greek lexicon for object
-at point. If not found in hash table, get it from sword database.
-stash in hash table, and return string.
-Note: compiler warns about unused `window' argument."
-  (let* ((query (get-text-property pos 'strong object))  ; Get Strong's number from text property
-	 (match (string-match "[0-9]+" query)) ; Compiler warns about unused match variable.
-	 (lookup-key (match-string 0 query)))
-    (bm--lookup-lex-greek lookup-key)))
+  "Look up Greek lexical entry of OBJECT clicked on in WINDOW at POS.
+If not found in hash table, get it from sword database. stash in hash
+table, and return string.
+Note: compiler warns about unused `WINDOW' argument."
+  (let ((query (get-text-property pos 'strong object)))  ; Get Strong's number from text property
+    (when (string-match "[0-9]+" query)
+      (bm--lookup-lex-greek (match-string 0 query)))))
 
 
 (defun bm--lookup-strongs-greek-short (window object pos)
-  "Look up Greek lexical string from short Greek lexicon for object
-at point. If not found in hash table, get it from sword database, 
-stash in hash table, and return string.
+  "Look up shorter Greek lexical entry of OBJECT clicked on in WINDOW at POS.
+If not found in hash table, get it from sword database, stash in hash table, 
+and return string.
 Note: compiler warns about unused `window' argument."
-  (let* ((query (get-text-property pos 'strong object))  ; Get Strong's number from text property
-	 (match (string-match "[0-9]+" query)) ; Compiler warns about unused match variable.
-	 (lookup-key (match-string 0 query)))
-    ;; Easier to debug longer version.
-;;; (when lookup-key
-;;;   (or (gethash lookup-key greek-hash-short)
-;;;	  (puthash lookup-key (bm--lex-query lookup-key bm-greek-lexicon-short) greek-hash-short)))
-    (when lookup-key
-      (let ((data (gethash lookup-key greek-hash-short)))
-	(if data data
-	  (let ((raw-text (bm--lex-query lookup-key bm-greek-lexicon-short)))
-	    (puthash lookup-key raw-text greek-hash-short)))))))
-      
+  (let ((query (get-text-property pos 'strong object)))  ; Get Strong's number from text property
+    (when (string-match "[0-9]+" query)
+      (let ((lookup-key (match-string 0 query)))
+	(or (gethash lookup-key greek-hash-short)
+	    (let ((raw-text (bm--lex-query lookup-key bm-greek-lexicon-short)))
+	      (puthash lookup-key raw-text greek-hash-short)))))))
 
 
 (defun bm--lookup-strongs-hebrew (window object pos)
@@ -865,15 +882,11 @@ Note: compiler warns about unused `window' argument."
 If not found in hash table, get it from sword database, 
 stash in hash table, and return string.
 Note: compiler warns about unused `window' argument."
-  (let* ((query (get-text-property pos 'strong object))
-	 (match (string-match "[0-9]+" query))         ; Compiler warns about match.
-	 (match-string (match-string 0 query)))
-    (when match-string
+  (let ((query (get-text-property pos 'strong object)))
+    (when (string-match "[0-9]+" query)
       (let ((lookup-key (concat "H" (match-string 0 query))))
 	(or (gethash lookup-key hebrew-hash)
-	    ;; Use PLAIN format for lookup. XXX directionality problems.
 	    (let ((raw-text (bm--lex-query lookup-key bm-hebrew-lexicon)))
-	      ;; XXX massage this text to handle outline formatting a bit better.
 	      (puthash lookup-key raw-text hebrew-hash)))))))
 
 (defun bm--lookup-strongs-hebrew-short (window object pos)
@@ -881,15 +894,11 @@ Note: compiler warns about unused `window' argument."
 at point. If not found in hash table, get it from sword database, 
 stash in hash table, and return string.
 Note: compiler warns about unused `window' argument."
-  (let* ((query (get-text-property pos 'strong object))
-	 (match (string-match "[0-9]+" query))         ; Compiler warns about match.
-	 (match-string (match-string 0 query)))
-    (when match-string
+  (let ((query (get-text-property pos 'strong object)))
+    (when (string-match "[0-9]+" query)
       (let ((lookup-key (concat "H" (match-string 0 query))))
 	(or (gethash lookup-key hebrew-hash-short)
-	    ;; Use PLAIN format for lookup. XXX directionality problems.
 	    (let ((raw-text (bm--lex-query lookup-key bm-hebrew-lexicon-short)))
-	      ;; XXX massage this text to handle outline formatting a bit better.
 	      (puthash lookup-key raw-text hebrew-hash-short)))))))
 
 (defun bm--morph-database-lookup (query database hash)
@@ -966,9 +975,10 @@ lex definition."
 
 
 (defun bm--process-word (item iproperties)
-  "Word study. Add tooltips for definitions and morphologyl. 
-Insert lemmas in buffer. Must be done after item is inserted in buffer."
-  (let ((word (dom-text item))
+  "Handle <w ....> fubar </w> tag. Add tooltips for definitions and morphology. 
+Also insert lemmas in buffer (must be done after item is inserted in
+buffer)."
+  (let ((word (string-trim (dom-text item)))
 	(morph (dom-attr item 'morph))
 	(savlm (dom-attr item 'savlm))
 	(lemma (dom-attr item 'lemma))
@@ -984,7 +994,9 @@ Insert lemmas in buffer. Must be done after item is inserted in buffer."
 	(add-face-text-property refstart refend '(:foreground "red")))
 
       ;; Special case this. XXX Some modules do this differently.
-      (when divinename (bm-handle-divine-name item))
+      (when divinename
+	(insert " ")
+	(bm-handle-divine-name item))
 
       ;; lexical definitions
       (when (or savlm lemma)
@@ -1043,32 +1055,28 @@ produced by `bm--exec-diatheke'. Outputs text to active buffer
 with properties.
 In processing subnodes, each case will prepend a space if it needs it."
 
-  (if (and bm-red-letter-enabled (equal (dom-attr node 'who) "Jesus"))
-      ;; For red-letter display.
-      (setq iproperties (plist-put iproperties 'jesus t))
-    (setq iproperties nil))
+  (when (and bm-red-letter-enabled (equal (dom-attr node 'who) "Jesus"))
+    ;; For red-letter display.
+    (setq iproperties (plist-put iproperties 'jesus t)))
 
   (dolist (subnode (dom-children node))
     (cond ((null subnode) nil)
 	  ((stringp subnode)
-	   ;; This still goes wrong, but I blame it on the module. ESV2011 in particular.
-	   (let ((verse-start (string-match bm-verse-regexp subnode)))
-	     (if verse-start
-		 (progn
-		   (when (= verse-start 0)
-		     (bm-new-line))
-		   ;; Insert the subnode. Highlight the verse references.
-		   (insert subnode)
-		   (let* ((verse-match (string-trim (match-string 0 subnode)))
-			  (verse-start-text (string-trim-left (substring subnode verse-start (length subnode))))
-			  (start (- (point) 1 (length (string-trim-right verse-start-text)))))
-		     (add-face-text-property start (+ start (length (string-trim-right verse-match))) '(:foreground "purple"))))
-	       (insert subnode)))
-	   ;; Red letter (some modules just have to be different....)
+	   (let* ((search-string (concat (car bm-current-book) " " (number-to-string bm-current-chapter) ":"))
+		  (match (string-match search-string subnode)))
+	     (when match
+	       (setf subnode (string-replace search-string "" subnode))
+	       (let ((match (string-match "[0-9]+:" subnode)))
+		 ;; Verse number
+		 (add-face-text-property (match-beginning 0) (match-end 0) '(:foreground "purple") nil subnode))))
+	   ;; Red letter
 	   (when (plist-get iproperties 'jesus)
-	     (add-face-text-property (- (point) (length subnode)) (point) '(:foreground "red"))))
-	  ((eq (dom-tag subnode) 'title) 
-	   (when (not notitle) (setq bm-chapter-title subnode)))
+	     (add-face-text-property 0 (length subnode) '(:foreground "red") nil subnode))
+	   (insert subnode))
+;;;	  ((eq (dom-tag subnode) 'node) nil)
+;;;	  ((eq (dom-tag subnode) 'lb) nil)
+	  ((eq (dom-tag subnode) 'title)
+	   (when (not notitle) (setq bm-chapter-title subnode) (bm-new-line)))
 	  ((eq (dom-tag subnode) 'body) (bm--insert-domnode-recursive subnode iproperties notitle))
 	  ((eq (dom-tag subnode) 'seg) ; NASB Module uses this to indicate OT quotations (and others?).
 	   (bm--insert-domnode-recursive subnode iproperties notitle))
@@ -1076,7 +1084,13 @@ In processing subnodes, each case will prepend a space if it needs it."
 	  ;; This tag is used for red letter.
 	  ((eq (dom-tag subnode) 'q) (bm--insert-domnode-recursive subnode iproperties notitle))
 	  ((eq (dom-tag subnode) 'p) (bm--insert-domnode-recursive subnode iproperties notitle))
-	  ((eq (dom-tag subnode) 'w) (insert " ") (bm--process-word subnode iproperties))
+	  ((eq (dom-tag subnode) 'w)
+	   (insert " ")
+	   (bm--process-word subnode iproperties))
+	  ((and (eq (dom-tag subnode) 'l) (equal (cdr (assoc 'type (dom-attributes subnode))) "x-br"))
+	   (bm-new-line))
+	  ((and (eq (dom-tag subnode) 'l) (equal (cdr (assoc 'type (dom-attributes subnode))) "x-indent"))
+	   (insert "	"))
 	  ((and (eq (dom-tag subnode) 'milestone) (equal (cdr (assoc 'type (dom-attributes subnode))) "line"))
 	   (bm-new-line))
 	  ((or (eq (dom-tag subnode) 'transchange) 
@@ -1084,13 +1098,16 @@ In processing subnodes, each case will prepend a space if it needs it."
 	   ;; Word inserted by translation, not in original, give visual indication.
 	   (let ((word (dom-text subnode)))
 	     (insert " " word)
-	     (add-face-text-property (- (point) (length word)) (point) '(:foreground "gray50")))))))
+	     (if (plist-get iproperties 'jesus)
+		 (add-face-text-property (- (point) (length word)) (point) '(:foreground "salmon"))
+	       (add-face-text-property (- (point) (length word)) (point) '(:foreground "gray50"))))))))
 
 
 (defvar bm-debugme nil)
 
 (defun bm--display (&optional verse)
-  "Renders text for `bible-mode'"
+  "Render text for `bible-mode'. 
+If VERSE is supplied, set cursor at verse."
 
   ;; Clear buffer and insert the result of calling bm--exec-diatheke.
   (setq buffer-read-only nil)
@@ -1103,21 +1120,18 @@ In processing subnodes, each case will prepend a space if it needs it."
   ;; Parse the xml in the buffer into a DOM tree.
   (let ((html-dom-tree (libxml-parse-html-region (point-min) (point-max))))
     ;; Render the DOM tree into the buffer.
-    (if (not bm-debugme)
-	(progn
-	  (erase-buffer)
-	  ;; Looking for the "body" tag in the DOM node.
-	  (bm--insert-domnode-recursive (dom-by-tag html-dom-tree 'body) nil nil)
-	  (goto-char (point-min)))
-;;;      (shr-render-region (point-min) (point-max))
-      ))
+    (unless bm-debugme
+      (erase-buffer)
+      ;; Looking for the "body" tag in the DOM node.
+      (bm--insert-domnode-recursive (dom-by-tag html-dom-tree 'body) nil nil)
+      (goto-char (point-min))))
 
   ;; Remove the module name from the buffer.
   (while (search-forward (concat "(" bm-module ")") nil t)
     (replace-match ""))
 
   ;; Set the mode line of the biffer.
-  (setq mode-name (concat "Bible (" 
+  (setq mode-name (concat "Bible (" bm-current-book-name " " (number-to-string bm-current-chapter) ") "
 			  bm-module
 			  (when bm-has-strongs " Lex")
 			  (when bm-has-morphology " Morph")
@@ -1138,6 +1152,27 @@ In processing subnodes, each case will prepend a space if it needs it."
 	  (setq refend (point))
 	  (put-text-property refstart refend 'face 'bold))))
 
+  ;; Get rid of spurious spaces.
+  (format-replace-strings '(("." . ". ")
+			    ("," . ", ")
+			    (";" . "; ")
+			    (":" . ": ")
+			    ("?" . "? ")
+			    ("!" . "! ")
+			    (" ." . ". ")
+			    (" ," . ", ")
+			    (" ;" . "; ")
+			    (" :" . ": ")
+			    (" ?" . "? ")
+			    (" !" . "! ")
+			    ("“ " . "“")
+			    ("‘ " . "‘")
+;;;			    (" ”" . "”")
+;;;			    (" ’" . "’")
+			    ("  " . " ")
+			    )
+			  nil (point-min) (point-max))
+
   (setq buffer-read-only t)
   (goto-char (point-min))
 
@@ -1148,7 +1183,7 @@ In processing subnodes, each case will prepend a space if it needs it."
 
 
 (defun bm--list-biblical-modules ()
-  "Returns a list of accessible Biblical Text modules."
+  "Return a list of accessible Biblical Text modules."
   (let ((text (bm--exec-diatheke "modulelist" nil nil nil "system"))
 	modules)
     (catch 'done
@@ -1160,6 +1195,7 @@ In processing subnodes, each case will prepend a space if it needs it."
     modules))
 
 (defun bm-pick-module ()
+  "Keymap action function---select module user chooses."
   (interactive)
   (let ((item (get-text-property (point) 'module)))
     (setq-default bm-module item)
@@ -1171,6 +1207,7 @@ In processing subnodes, each case will prepend a space if it needs it."
 
 
 (defun bm-display-available-modules ()
+  "Display available modules, allow user to select."
   (interactive)
   (let ((buf (get-buffer-create "Modules"))
 	(mods (bm--list-biblical-modules)))
@@ -1197,16 +1234,17 @@ In processing subnodes, each case will prepend a space if it needs it."
 
 ;;;;; Bible Searching
 
-(defun bm--open-search (query searchmode module)
-  "Opens a search buffer of QUERY using SEARCHMODE."
-  (let ((buf (get-buffer-create (concat "*bible-search-" (downcase module) "-" query "*"))))
+(defun bm--open-search (query searchmode mod)
+  "Open a search buffer of QUERY using SEARCHMODE in module MOD."
+  (let ((buf (get-buffer-create (concat "*bible-search-" (downcase mod) "-" query "*"))))
     (set-buffer buf)
     (bible-search-mode)
-    (bm--display-search query searchmode module)
+    (bm--display-search query searchmode mod)
     (pop-to-buffer buf nil t)))
 
 (defun bm--display-search (query searchmode mod)
-  "Renders results of search QUERY from SEARHCMODE"
+  "Render results of search QUERY from SEARCHMODE.
+Module MOD is used for the query."
   (setq buffer-read-only nil)
   (erase-buffer)
   
@@ -1219,7 +1257,10 @@ In processing subnodes, each case will prepend a space if it needs it."
 	 (query-verses "")
 	 fullverses)
     (if (equal result (concat "none (" mod ")"))
-	(insert "No results found." (when (equal searchmode "lucene") " Verify index has been build with mkfastmod."))
+	(insert "No results found."
+		(if (equal searchmode "lucene")
+		    " Verify index has been build with mkfastmod."
+		  ""))
       (progn
 	(while match
 	  (setq match (string-match ".+?:[0-9]?[0-9]?" result (+ match (length matchstr)))
@@ -1233,9 +1274,7 @@ In processing subnodes, each case will prepend a space if it needs it."
 	      "I " "1"
 	      (replace-regexp-in-string
 	       "II " "2"
-	       (replace-regexp-in-string
-		"III " "3"
-	       (replace-regexp-in-string ".+; " "" matchstr))))
+	       (replace-regexp-in-string ".+; " "" matchstr)))
 	     verses)))
 
 	(setq match 0)
@@ -1244,7 +1283,7 @@ In processing subnodes, each case will prepend a space if it needs it."
 	  (if query-verses
 	      (setq query-verses (concat query-verses ";" verse))
 	    (setq query-verses verse)))
-	(setq fullverses (bm--exec-diatheke query-verses nil nil nil mod))
+	(setq fullverses (let ((bm-show-diatheke-exec nil)) (bm--exec-diatheke query-verses nil nil nil mod)))
 
 	(insert fullverses)
 	    
@@ -1269,26 +1308,20 @@ In processing subnodes, each case will prepend a space if it needs it."
 ;;  )
 
 (defun bm--display-term (termtype)
-  (message "bible-mode--display-term %s" termtype)
 
   (setq buffer-read-only nil)
 
-  (cl-do* ((text (buffer-string))
-	   (match (string-match "[0-9]+" text) (string-match "[0-9]+" text (match-end 0))))
-      ((not match))
-    ;; This enables clicking on the Strong's numbers inside the term display.
-    (let* ((matchstr (match-string 0 text))
-	   (matchstrlen (length matchstr))
-           (refstart (+ match 1))
-           (refend (+ match 1 matchstrlen)))
-      (cond ((eq termtype 'hebrew)
-	     (put-text-property refstart refend 'strong (concat "strong:H" matchstr))
-	     (put-text-property refstart refend 'keymap bm-hebrew-keymap)
-	     (add-face-text-property refstart refend `(:foreground "blue")))
-	    ((eq termtype 'greek)
-	     (put-text-property refstart refend 'strong (concat "strong:G" matchstr))
-	     (put-text-property refstart refend 'keymap bm-greek-keymap)
-	     (add-face-text-property refstart refend `(:foreground "blue"))))))
+  (goto-char (point-min))
+  ;; This enables clicking on Strong's numbers in some lexicon definitions.
+  (while (search-forward-regexp "[0-9]+" nil t)
+    (cond ((eq termtype 'hebrew)
+	   (put-text-property (match-beginning 0) (match-end 0) 'strong (concat "strong:H" (match-string 0)))
+	   (put-text-property (match-beginning 0) (match-end 0) 'keymap bm-hebrew-keymap)
+	   (add-face-text-property (match-beginning 0) (match-end 0) `(:foreground "blue")))
+	  ((eq termtype 'greek)
+	   (put-text-property (match-beginning 0) (match-end 0) 'strong (concat "strong:G" (match-string 0)))
+	   (put-text-property (match-beginning 0) (match-end 0) 'keymap bm-greek-keymap)
+	   (add-face-text-property (match-beginning 0) (match-end 0) `(:foreground "blue")))))
 
   (goto-char (point-min))
 
@@ -1297,20 +1330,17 @@ In processing subnodes, each case will prepend a space if it needs it."
     (put-text-property (match-beginning 0) (match-end 0) 'xref (match-string 0))
     (put-text-property (match-beginning 0) (match-end 0) 'keymap bible-search-mode-map)
     (put-text-property (match-beginning 0) (match-end 0) 'help-echo (concat "Go to " (match-string 0)))
-    (add-face-text-property (match-beginning 0) (match-end 0) '(:foreground "blue"))
-    )
+    (add-face-text-property (match-beginning 0) (match-end 0) '(:foreground "blue")))
   (goto-char (point-min))
 
-;;  (while (search-forward (concat "(" bm-module ")") nil t)
-;;    (replace-match ""))
-
   (while (search-forward "()" nil t)
     (replace-match ""))
   (goto-char (point-min))
   (setq buffer-read-only t))
 
+
 (defun bm--open-term-hebrew (term)
-  "Opens a buffer of the Strong's Hebrew TERM's definition"
+  "Open a buffer of the Strong's Hebrew TERM's definition."
   (let ((buf (get-buffer-create (concat "*bible-term-hebrew-" term "*"))))
     (set-buffer buf)
     (bible-term-hebrew-mode)
@@ -1319,7 +1349,7 @@ In processing subnodes, each case will prepend a space if it needs it."
     (fit-window-to-buffer)))
 
 (defun bm--open-term-greek (term)
-  "Opens a buffer of the Strong's Greek TERM's definition"
+  "Open a buffer of the Strong's Greek TERM definition."
   (let ((buf (get-buffer-create (concat "*bible-term-greek-" term "*"))))
     (set-buffer buf)
     (bible-term-greek-mode)
@@ -1331,8 +1361,8 @@ In processing subnodes, each case will prepend a space if it needs it."
 ;;; Note: Hebrew display of terms is backwards; set bidi direction to
 ;;; 'left-to-right.
 (defun bm--display-term-hebrew (term)
-  "Render the definition of the Strong's Hebrew TERM. Use
-bidi-paragraph-direction so the English text will render
+  "Render the definition of the Strong's Hebrew TERM. 
+Sets bidi-paragraph-direction so the English text will render
 left-to-right. XXX Why doesn't this work for the tooltips?"
   (setq buffer-read-only nil)
   (erase-buffer)
@@ -1353,13 +1383,12 @@ left-to-right. XXX Why doesn't this work for the tooltips?"
   (insert (replace-regexp-in-string
 	     (regexp-opt `(,bm-greek-lexicon))
 	     ""
-	     ;;	     (bm--exec-diatheke term nil "plain" nil bm-greek-lexicon)
 	     (bm--lookup-lex-greek term)))
   (bm--display-term 'greek))
 
 
 (defun bm--set-location (book chapter &optional verse)
-  "Sets the global chapter of the active `bible-mode' buffer."
+  "Set the BOOK, CHAPTER and optionally VERSE of the active `bible-mode' buffer."
   (setq-local bm-current-book book)
   (setq-local bm-current-book-name (car book))
   (setq-local bm-current-chapter chapter)
@@ -1368,7 +1397,8 @@ left-to-right. XXX Why doesn't this work for the tooltips?"
 ;;;;; Utilities
 
 (defun bm--list-number-range (min max &optional prefix)
-  "Returns a list containing entries for each integer between min and max.
+  "Returns a list containing entries for each integer between MIN and MAX.
+If PREFIX is supplied, prepend PREFIX to the entries.
 Used in tandem with `completing-read' for chapter selection."
   (let ((range-list nil))
     (dotimes (num (1+ max))