diff --git a/ChangeLog b/ChangeLog
index cd77ec87..8dc5d02c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2026-07-23 Bob Weiner
+
+* hywiki.el (hywiki-get-entry): Strip file header when returning
+ definition as a string, as that is all should be desired.
+ (hywiki-get-definition, hywiki-get-entry): Change so just
+ returns nil if first arg is sent as a non-string or an empty string
+ rather than triggering an error.
+ (hywiki-display-glossary-entry): Don't display the entry if in
+ the middle of a 'hywiki-create-referent-and-display' call since that
+ displays the entry source buffer already.
+
+* hmouse-drv.el (hkey-help): Conditionalize HyWikiWord glossary entry
+ definition output on a non-nil 'lbl-key', i.e. non-nil reference.
+
+2026-07-22 Bob Weiner
+
+* test/hy-string-tests.el: Add to start 'hypb:in-string-p' testing.
+
+* man/hyperbole.texi (HyWiki Menu, HyWiki Glossary): Document the ways
+ to use HyWiki glossary entries.
+
+* hywiki.el (hywiki-get-term-variant-regexp): Allow the term to be
+ surrounded by Org emphasis characters.
+ (hywiki-get-term-variant-regexp): Fix to make case sensitive
+ so wikiwords are always split on capital letters properly.
+ hpath.el (hpath:org-normalize-title): Strip any Org emphasis characters.
+ (hywiki-get-entry): Obey 'regexp-flag' when calling
+ 'hyrolo-grep-file'.
+ (hydef): Add macro to use as an Action Button to display HyWiki
+ glossary definitions.
+
2026-07-22 Mats Lidell
* test/hywiki-tests.el (hywiki-tests--potential-buffer-p): New test.
diff --git a/hmouse-drv.el b/hmouse-drv.el
index cfe0de44..a200733c 100644
--- a/hmouse-drv.el
+++ b/hmouse-drv.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 04-Feb-90
-;; Last-Mod: 20-Jul-26 at 01:47:30 by Bob Weiner
+;; Last-Mod: 23-Jul-26 at 00:17:46 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -1185,15 +1185,15 @@ documentation is found."
;; Print Hyperbole button attributes
(when (memq cmd-sym '(hui:hbut-act hui:hbut-help))
- (let* ;; (lbl-key (hattr:get 'hbut:current 'lbl-key))
- ((categ (hattr:get 'hbut:current 'categ))
- (attributes (nthcdr 2 (hattr:list 'hbut:current)))
- (but-def-symbol (htype:def-symbol
- (if (eq categ 'explicit) actype categ)))
- (wikiword-referent
- (when (eq (htype:def-symbol actype) 'link-to-wikiword)
- (hywiki-get-referent
- (hattr:get 'hbut:current 'lbl-key)))))
+ (let* ((lbl-key (hattr:get 'hbut:current 'lbl-key))
+ (categ (hattr:get 'hbut:current 'categ))
+ (attributes (nthcdr 2 (hattr:list 'hbut:current)))
+ (but-def-symbol (htype:def-symbol
+ (if (eq categ 'explicit) actype categ)))
+ (wikiword-referent
+ (when (eq (htype:def-symbol actype) 'link-to-wikiword)
+ (hywiki-get-referent
+ (hattr:get 'hbut:current 'lbl-key)))))
(when wikiword-referent
(hattr:set 'hbut:current 'referent-type
@@ -1219,16 +1219,17 @@ documentation is found."
;; (hypb:remove-from-plist attributes 'action))
(hattr:report attributes)
- ;; Need to save and restore 'hbut:current here since
- ;; hywiki-get-definition overwrites it
- (unwind-protect
- (progn (hattr:copy 'hbut:current 'saved-but)
- (setq def (hywiki-get-definition
- (ibut:key-to-label (hattr:get 'hbut:current 'lbl-key))))
- (when def
- (terpri)
- (princ def)))
- (hattr:copy 'saved-but 'hbut:current))
+ (when lbl-key
+ (unwind-protect
+ ;; Need to save and restore 'hbut:current here
+ ;; since hywiki-get-definition overwrites it
+ (progn (hattr:copy 'hbut:current 'saved-but)
+ (setq def (hywiki-get-definition
+ (ibut:key-to-label lbl-key)))
+ (when (stringp def)
+ (terpri)
+ (princ def)))
+ (hattr:copy 'saved-but 'hbut:current)))
(unless (or assisting
(eq categ 'explicit)
diff --git a/hpath.el b/hpath.el
index 399f2f62..a22b5121 100644
--- a/hpath.el
+++ b/hpath.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 1-Nov-91 at 00:44:23
-;; Last-Mod: 16-Jul-26 at 16:57:49 by Bob Weiner
+;; Last-Mod: 22-Jul-26 at 15:13:47 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -1754,7 +1754,9 @@ but locational suffixes within the file are utilized."
"Ignore HASH when ANCHOR is non-null and move point to ANCHOR string if found.
Move point to beginning of buffer if HASH is non-nil and ANCHOR is null.
With optional INSTANCE-NUM, go to that instance of ANCHOR from the start
-of the buffer."
+of the buffer.
+
+Trigger an error if the instance of the non-null anchor requested is not found."
(let ((omin (point-min))
(omax (point-max)))
(unwind-protect
@@ -2026,7 +2028,8 @@ form is what is returned for PATH."
(defun hpath:org-normalize-title (title)
"Return title in normalized form.
-Strip all priority, leading ':' or '-' separators, and stats from TITLE."
+Strip all priority, leading ':' or '-' separators, stats and Org emphasis
+characters from TITLE."
(when title
(let ((clean (copy-sequence title)))
;; Strip leading priority: [#B] or [#2} followed by ':' or '-' surrounded by any whitespace
@@ -2035,7 +2038,11 @@ Strip all priority, leading ':' or '-' separators, and stats from TITLE."
;; Matches: "- Title", ": Title", " - Title"
(setq clean (string-trim (replace-regexp-in-string "\\`[ \t]*[-:][ \t]+" "" clean)))
;; Strip trailing statistics cookies [1/2] or [50%]
- (setq clean (replace-regexp-in-string "\\(?: +\\[[0-9%+/]+\\]\\)+\\'" "" clean)))))
+ (setq clean (replace-regexp-in-string "\\(?: +\\[[0-9%+/]+\\]\\)+\\'" "" clean))
+ ;; Strip *bold*’, ‘/italic/’, ‘_underlined_’, ‘=verbatim=’ and ‘~code~’
+ ;; Org emphasis characters
+ (setq clean (replace-regexp-in-string "\\`[ \t]*[*/_=~]\\(.+\\)[*/_=~]"
+ "\\1" clean)))))
(defun hpath:org-normalize-titles ()
"Get all buffer Org titles in normalized form.
diff --git a/hyperbole.el b/hyperbole.el
index 92343f9d..9a3cee20 100644
--- a/hyperbole.el
+++ b/hyperbole.el
@@ -9,7 +9,7 @@
;; Maintainer: Robert Weiner
;; Maintainers: Robert Weiner , Mats Lidell
;; Created: 06-Oct-92 at 11:52:51
-;; Last-Mod: 14-Jul-26 at 10:01:48 by Bob Weiner
+;; Last-Mod: 22-Jul-26 at 11:15:05 by Bob Weiner
;; Released: 10-Mar-24
;; Version: 9.0.2pre
;; Keywords: comm, convenience, files, frames, hypermedia, languages, mail, matching, mouse, multimedia, outlines, tools, wp
@@ -354,20 +354,21 @@ of the commands."
;; f = SELECTED_FRAME ();
;; XSETFRAME (lispy_dummy, f);
;;
-;; It seems like the XSETFRAME macro is not properly copying the value of f on initial frame selection under the macOS window system.
-;; The problem occurs on other systems as well, e.g. Emacs 25.2 under Windows 7.
+;; It seems like the XSETFRAME macro is not properly copying the value of f
+;; on initial frame selection under the macOS window system. The problem
+;; occurs on other systems as well, e.g. Emacs 25.2 under Windows 7.
;;
;; Hyperbole resolves this problem by setting the
;; `mouse-position-function' variable below to properly set the
;; newly selected frame.
-(if (boundp 'mouse-position-function)
- (setq mouse-position-function
- (lambda (frame-x-dot-y)
- "Make `mouse-position' and `mouse-pixel-position' return the selected frame.
+(when (boundp 'mouse-position-function)
+ (setq mouse-position-function
+ (lambda (frame-x-dot-y)
+ "Make `mouse-position' and `mouse-pixel-position' return the selected frame.
Under macOS and Windows 7 at least, upon initial selection of a new
frame, those functions by default still return the prior frame."
- (if (consp frame-x-dot-y) (setcar frame-x-dot-y (selected-frame)))
- frame-x-dot-y)))
+ (if (consp frame-x-dot-y) (setcar frame-x-dot-y (selected-frame)))
+ frame-x-dot-y)))
;; hmouse-drv will load hui-mouse and hmouse-key
(mapc #'require '(hsettings hmouse-drv hmouse-sh))
diff --git a/hywiki.el b/hywiki.el
index ac2cd9cb..f964176a 100644
--- a/hywiki.el
+++ b/hywiki.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 21-Apr-24 at 22:41:13
-;; Last-Mod: 21-Jul-26 at 01:46:11 by Bob Weiner
+;; Last-Mod: 23-Jul-26 at 11:38:51 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -1449,7 +1449,7 @@ calling this function."
(gbut:act gbut-name))
(defun hywiki-add-glossary-entry (term)
- "Add TERM as a new HyWiki glossary entry to be defined."
+ "Add/edit TERM as a HyWiki glossary entry with a definition."
(let ((glossary (hywiki-get-glossary-file))
(hyrolo-date-format "")) ;; don't add a date
(if (= 1 (hyrolo-grep (hywiki-get-term-variant-regexp term)
@@ -1461,14 +1461,20 @@ calling this function."
;; Skip past file header
(hyrolo-to-next-entry)
(hyrolo-edit-entry))
- ;; add a new entry
+ ;; add a new definition entry using the original term, not any
+ ;; wikiword transformed version
(hyrolo-add term glossary)))
+ ;; Connect wikiword version of term to the glossary definition
(hywiki-add-referent (hywiki-string-to-wikiword term)
(cons 'glossary-entry term)))
(defun hywiki-display-glossary-entry (_wikiword term)
"Display any HyWiki glossary definition for TERM."
- (hywiki-get-definition term t))
+ ;; Don't display the entry if in the middle of a
+ ;; `hywiki-create-referent-and-display' call since that displays the entry
+ ;; source buffer already.
+ (unless (hyperb:stack-frame '(hywiki-create-referent-and-display))
+ (hywiki-get-definition term t)))
(defun hywiki-add-hyrolo (wikiword)
"Make WIKIWORD search and display `hyrolo-file-list' matches.
@@ -2413,8 +2419,12 @@ therein is invalid, trigger an error."
(defun hywiki-get-term-variant-regexp (term)
"Return a grouped regexp of the allowed glossary variants for TERM string."
- (let (str)
- (format "\\(%s\\|%s\\|%s\\|%s\\)"
+ ;; Allow for term downcased, and/or with spaces between capitalized words
+ ;; or the whole term capitalized. Also allow the term to be surrounded by
+ ;; Org emphasis characters.
+ (let ((str)
+ (case-fold-search nil))
+ (format "[*/_=~]?\\(%s\\|%s\\|%s\\|%s\\)[*/_=~]?"
(regexp-quote term)
(regexp-quote (downcase term))
(regexp-quote (setq str (hywiki-wikiword-to-string term " ")))
@@ -2423,12 +2433,13 @@ therein is invalid, trigger an error."
;;;###autoload
(defun hywiki-get-definition (term &optional display-flag file)
"Return or display the HyWiki glossary definition string for TERM.
-Return nil if no match is found.
+Return nil if TERM is not a string, if TERM is the empty string or no match
+is found.
If called interactively or with optional DISPLAY-FLAG non-nil, display a
buffer with TERM's definition but don't return it. Get definition from
HyWiki's Glossary.org or optional FILE. If the file is not readable or no
-matching TERM entry is found, return nil.
+matching TERM entry is found, return nil; othewise, return t.
If the `consult' package is installed, interactively select and complete
the entry to be inserted.
@@ -2448,35 +2459,46 @@ top-level headlines are searched.
(interactive (list (hywiki-completing-read-glossary-term
"HyWiki glossary definition of: ")
nil t))
- (when (or (not (stringp term)) (string-empty-p term))
- (error "(hywiki-get-definition): Invalid `term': `%s'" term))
- (let ((glossary (hywiki-get-glossary-file file))
- (term-regexp (hywiki-get-term-variant-regexp term))
- entry)
- (setq entry
- (cond ((cl-find ?# term)
- ;; WikiWord#section or #section
- (hywiki-get-entry term-regexp display-flag nil t))
- ((or (hywiki-word-is-p term t) (null file))
- ;; Is a WikiWord or phrase only; match to any of several
- ;; forms: WikiWord, wikiword, Wiki Word, wiki word
- (when (file-readable-p glossary)
- (hywiki-get-entry (concat (if file "" "Glossary#") term-regexp)
- display-flag file t)))
- (t
- (cond ((or (not (stringp file)) (string-empty-p file))
- (error "(hywiki-get-definition): \"%s\" is invalid" file))
- (t
- ;; phrase with a file to search
- (hywiki-get-entry term-regexp display-flag file t))))))
- (when (stringp entry)
- ;; Remove * or # prefix from def entry before returning, so can be
- ;; embedded in other doc
- (setq entry (substring entry (if (string-match "\\`[*#]+[ \t\n\f]*"
- entry)
- (match-end 0)
- 0)))
- (if display-flag t entry))))
+ (when (and (stringp term) (not (string-empty-p term)))
+ (let ((glossary (hywiki-get-glossary-file file))
+ entry
+ index
+ term-regexp
+ wikiword)
+ (cond ((setq index (seq-position term ?#))
+ ;; WikiWord#section or #section
+ (setq wikiword (substring term 0 index)
+ term (substring term (1+ index))
+ term-regexp (hywiki-get-term-variant-regexp term)
+ file (if (zerop index)
+ buffer-file-name
+ (hywiki-get-page-file wikiword))))
+ ((or (hywiki-word-is-p term t) (null file))
+ ;; Is a WikiWord or phrase only; match to any of several
+ ;; forms: WikiWord, wikiword, Wiki Word, wiki word -- in
+ ;; file when given or the Glossary file when not
+ (when (file-readable-p glossary)
+ (setq term-regexp (hywiki-get-term-variant-regexp term))
+ (unless (and (stringp file) (not (string-empty-p file)))
+ (setq file glossary))))
+ (t
+ ;; `file' is non-null so try to use that or trigger an error
+ (when (or (not (stringp file)) (string-empty-p file)
+ (not (file-readable-p file)))
+ (error "(hywiki-get-definition): \"%s\" is invalid" file))
+ (setq term-regexp (hywiki-get-term-variant-regexp term))))
+
+ ;; Return and possibly display matching definition
+ (setq entry (hywiki-get-entry term-regexp display-flag file t))
+
+ (when (stringp entry)
+ ;; Remove * or # prefix from def entry before returning, so can be
+ ;; embedded in other doc
+ (setq entry (substring entry (if (string-match "\\`[*#]+[ \t\n\f]*"
+ entry)
+ (match-end 0)
+ 0))))
+ entry)))
(defun hywiki-get-delimited-region ()
"Immediately before or after a balanced delimiter, return the delimited range.
@@ -2526,14 +2548,20 @@ This includes the delimiters: (), {}, <>, [] and \"\" (double quotes)."
;;;###autoload
(defun hywiki-get-entry (reference &optional display-flag file regexp-flag)
"Return a string of the first HyWiki entry headline containing REFERENCE.
-Return nil if no match is found.
+Return nil if REFERENCE is not a string, if REFERENCE is the empty string or
+no match is found.
If called interactively or with optional DISPLAY-FLAG non-nil, display a
-buffer with REFERENCE's definition but don't return it. Get definition from
-HyWiki's Glossary.org, optional FILE, or the current buffer for #in-file
-references. If the file is not readable or no matching REFERENCE entry is
-found, return nil. With optional prefix arg, REGEXP-FLAG, treat REFERENCE
-as a regular expression instead of a string.
+buffer with REFERENCE's definition but don't return it. If the file is not
+readable or no matching REFERENCE entry is found, return nil; othewise,
+return t.
+
+Get definition from HyWiki's Glossary.org, optional FILE, or the current
+buffer for #in-file references. Trigger an error if an invalid non-nil FILE
+argument is sent.
+
+With optional prefix arg, REGEXP-FLAG, treat REFERENCE as a regular
+expression instead of a string.
If the `consult' package is installed, interactively select and complete
the entry to be inserted.
@@ -2551,22 +2579,18 @@ top-level headlines are searched.
|------------------+------+---------------+----------------------------------|"
(interactive (list (hywiki-read-headline-regexp "Return")
current-prefix-arg))
- (when (and (stringp reference) (string-empty-p reference))
- (setq reference nil))
- (when (or (null reference) (not (stringp reference)))
- (error "(hywiki-get-entry): Invalid reference: `%s'" reference))
-
- (let ((buf (current-buffer))
- (buf-file buffer-file-name)
- (found 0)
- (word-end (hywiki-word-is-p reference t))
- (consult-flag (and (called-interactively-p 'interactive) (hsys-consult-active-p)))
- (phrase "")
- entry-to-match
- path-list)
- (save-window-excursion
- (with-current-buffer (get-buffer-create hywiki-glossary-display-buffer)
- (let ((hyrolo-display-buffer hywiki-glossary-display-buffer))
+ (when (and (stringp reference) (not (string-empty-p reference)))
+ (let ((hyrolo-display-buffer hywiki-glossary-display-buffer)
+ (buf-file buffer-file-name)
+ (found 0)
+ (word-end (hywiki-word-is-p reference t))
+ (consult-flag (and (called-interactively-p 'interactive) (hsys-consult-active-p)))
+ (phrase "")
+ entry-to-match
+ path-list)
+ (save-window-excursion
+ (with-current-buffer (get-buffer-create hywiki-glossary-display-buffer)
+ (setq hyrolo-display-buffer hywiki-glossary-display-buffer)
;; (hyrolo--cache-initialize)
(cond ((or consult-flag
(not (string-match-p "#" reference))
@@ -2587,7 +2611,7 @@ top-level headlines are searched.
path-list (if buf-file
(list buf-file)
(user-error "(hywiki-get-entry): #section not allowed in non-file buffer: reference = %s; buffer = %S"
- reference buf))))
+ reference (get-buffer buf-file)))))
((not (string-empty-p phrase))
;; The phrase is a WikiWord; use this as the file to search
(setq path-list (list (expand-file-name
@@ -2609,27 +2633,57 @@ top-level headlines are searched.
(string-match "\\([^ \t\n\r\"'`]*[^ \t\n\r:\"'`0-9]\\): ?\\([1-9][0-9]*\\)[ :]"
reference)))
(hyrolo-grep-file (if path-list (car path-list) (match-string-no-properties 1 reference))
- (regexp-quote (if path-list
- entry-to-match
- (substring reference (match-end 0))))
+ (funcall (if regexp-flag #'identity #'regexp-quote)
+ (if path-list
+ entry-to-match
+ (substring reference (match-end 0))))
-1 nil t)
(hyrolo-grep (if regexp-flag entry-to-match (regexp-quote entry-to-match))
-1
(hyrolo-expand-path-list (or path-list (list hywiki-directory)))
- nil t (not display-flag))))))))
- (if display-flag
- (progn
- (hyrolo-display-matches)
- ;; skip past header to the entry
- (unless (zerop found)
- (hyrolo-to-next-entry)))
- (unless (zerop found)
- (with-current-buffer hyrolo-display-buffer
- (buffer-string))))))
+ nil t (not display-flag)))))))
+ (if display-flag
+ (if (zerop found)
+ (progn (beep)
+ (message "(hywiki-get-entry): No match for `%s' found in `%s'"
+ reference
+ (or path-list hywiki-directory))
+ nil)
+ ;; Display even if no entries are found
+ (hyrolo-display-matches)
+ ;; skip past header to the entry
+ (hyrolo-to-next-entry)
+ t)
+ (unless (zerop found)
+ (with-current-buffer hyrolo-display-buffer
+ (save-excursion
+ (goto-char (point-min))
+ ;; skip past header to the entry
+ (hyrolo-to-next-entry)
+ (buffer-substring (point) (point-max)))))))))
+
+;;;###autoload
+(defmacro hydef (&rest term)
+ "Display TERM's definition, which may be given as multiple strings or symbols.
+All of the following represent the same TERM: ActionKey, \"ActionKey\",
+Action Key, action key, and \"action key\", i.e. (hydef action key).
+
+Use this as a Hyperbole Action Button to hyperlink to an individual HyWiki
+definition from ${hywiki-directory}/Glossary.org), i.e. "
+ `(let ((term-str (mapconcat (lambda (word)
+ (cond ((symbolp word) (symbol-name word))
+ ((stringp word) word)
+ (t (format "%s" word))))
+ ',term " ")))
+ (when (or (null term-str) (member term-str '("" "t" "nil")))
+ (error "(hydef): No term given; must give a term to lookup the definition"))
+ (hywiki-get-definition term-str t)))
(defun hywiki-get-glossary-file (&optional file)
"Return the glossary file for the current HyWiki."
- (expand-file-name (or file (concat "Glossary" hywiki-file-suffix))
+ (expand-file-name (if (and (stringp file) (not (string-empty-p file)))
+ file
+ (concat "Glossary" hywiki-file-suffix))
hywiki-directory))
(defun hywiki-get-glossary-terms ()
@@ -3881,8 +3935,8 @@ When NO-STATS is non-nil, don't include statistics in square brackets."
"\\(?:[ \t]*\\(\\[#.\\]\\)\\)?"
;; title and optional stats
"\\(?:[ \t]*\\(%s\\)\\)")
- ;; exact title
- (regexp-quote title)))
+ ;; exact title in diff formats
+ (hywiki-get-term-variant-regexp title)))
(defun hywiki-org-get-publish-project ()
"Return the HyWiki Org publish project, a named set of properties.
diff --git a/man/hyperbole.texi b/man/hyperbole.texi
index 8ba6bd47..7812c45a 100644
--- a/man/hyperbole.texi
+++ b/man/hyperbole.texi
@@ -7,7 +7,7 @@
@c Author: Bob Weiner
@c
@c Orig-Date: 6-Nov-91 at 11:18:03
-@c Last-Mod: 20-Jul-26 at 01:29:18 by Bob Weiner
+@c Last-Mod: 22-Jul-26 at 23:56:16 by Bob Weiner
@c %**start of header (This is for running Texinfo on a region.)
@setfilename hyperbole.info
@@ -30,7 +30,7 @@
@set txicodequoteundirected
@set txicodequotebacktick
-@set UPDATED July 20, 2026
+@set UPDATED July 22, 2026
@set UPDATED-MONTH July 2026
@set EDITION 9.0.2pre
@set VERSION 9.0.2pre
@@ -171,7 +171,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Edition 9.0.2pre
-Printed July 20, 2026.
+Printed July 22, 2026.
Published by the Free Software Foundation, Inc.
Author: Bob Weiner
@@ -213,7 +213,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@example
Edition 9.0.2pre
-July 20, 2026 @c AUTO-REPLACE-ON-SAVE
+July 22, 2026 @c AUTO-REPLACE-ON-SAVE
Published by the Free Software Foundation, Inc.
@@ -5155,15 +5155,37 @@ reference is highlighted but no referent is displayed). Defer
referent creation until the first activation of the HyWikiWord, at
which point the HyWiki RefType menu is displayed for selection.
-@cindex menu item, HyWiki Glossary
+@cindex menu item, HyWiki glossarY
@cindex HyWiki Glossary reftype
@cindex HyWikiWord definition
@cindex definition, HyWikiWord
@findex hywiki-get-definition
+@anchor{HyWiki Glossary}
@item Glossary
-Add a HyWikiWord that displays its own definition from the HyWiki's
-Glossary.org file. See the documentation string for
-@code{hywiki-get-definition} for more detail.
+Add or edit the definition of a HyWikiWord that displays its own
+definition from the HyWiki's Glossary.org file.
+
+A HyWiki can contain a Glossary.org file with heading titles that
+represent terms associated with the HyWiki. The body of each heading
+section is the definition of the term. Terms can consist of multiple
+words and do not have to be HyWikiWords but may be.
+
+@noindent
+There are three ways to work with HyWiki glossary terms:
+
+@enumerate
+@item Use a @dfn{hydef} Action Button to display the term's definition.
+For example, @samp{} or @samp{}
+
+@item Create a HyWikiWord with a glossary referent type.
+With @code{hywiki-mode} active, @bkbd{M-0 M-RET y} or @bkbd{C-h h h c
+y} will turn the wikiword at point into or will prompt you for a
+wikiword name whose referent displays the definition for the wikiword.
+
+@item Programmatically display a glossary entry.
+Call @code{(hywiki-get-definition "term" t)} to display the entry.
+@end enumerate
+
@end table
@vindex hywiki-directory
@@ -8833,12 +8855,23 @@ publishes/exports an entire HyWiki to HTML for display on the web.
See the documentation for its implicit button types,
@code{hywiki-word} and @code{hywiki-existing-word}.
+@cindex glossary, HyWiki
+@cindex definition, HyWikiWord
+@cindex HyWikiWord definition
+@item HyWiki Glossary
+A HyWiki can contain a Glossary.org file with heading titles that
+represent terms associated with the HyWiki. The body of each heading
+section is the definition of the term. Terms can consist of multiple
+words and do not have to be HyWikiWords but may be.
+
+@xref{HyWiki Glossary}, for more details.
+
@item HyWikiWord
A @dfn{HyWikiWord}, or just wikiword, is a PascalCase word that starts
with a capital letter and contains upper and lowercase letters only
and has an associated referent (a link or an action). The default,
-most common referent type, is a @dfn{HyWiki Page}, an Org file with the
-wikiword's name and a @file{.org} suffix that lives in
+most common referent type, is a @dfn{HyWiki Page}, an Org file with
+the wikiword's name and a @file{.org} suffix that lives in
@code{hywiki-directory}.
HyWikiWords are automatically highlighted and turned into hyperlinks
diff --git a/test/MANIFEST b/test/MANIFEST
index 444cd43d..12da5c0f 100644
--- a/test/MANIFEST
+++ b/test/MANIFEST
@@ -19,6 +19,7 @@ hui-mouse-tests.el - hui-mouse and hkey-alist Action Key tests
hui-register-tests.el - test for hui-register
hui-select-tests.el - hui-select tests
hui-tests.el - tests for hui.el Hyperbole UI
+hy-string-tests.el - test whether point is inside or outside of a string
hy-test-coverage.el - provide test coverage information
hy-test-dependencies.el - Hyperbole test dependencies
hy-test-helpers.el - unit test helpers
diff --git a/test/demo-tests.el b/test/demo-tests.el
index 7587e246..8c5f0c88 100644
--- a/test/demo-tests.el
+++ b/test/demo-tests.el
@@ -1,9 +1,9 @@
;;; demo-tests.el --- unit tests from examples in the DEMO -*- lexical-binding: t; -*-
-
+;;
;; Author: Mats Lidell
;;
;; Orig-Date: 30-Jan-21 at 12:00:00
-;; Last-Mod: 16-Jun-26 at 22:09:58 by Bob Weiner
+;; Last-Mod: 22-Jul-26 at 23:49:19 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
diff --git a/test/hy-string-tests.el b/test/hy-string-tests.el
new file mode 100644
index 00000000..a24dce5b
--- /dev/null
+++ b/test/hy-string-tests.el
@@ -0,0 +1,97 @@
+;;; hy-string-tests.el --- test whether point is inside or outside of a string -*- lexical-binding: t; -*-
+;;
+;; Author: Bob Weiner
+;;
+;; Orig-Date: 22-Jul-26 at 23:41:29
+;; Last-Mod: 22-Jul-26 at 23:49:34 by Bob Weiner
+;;
+;; SPDX-License-Identifier: GPL-3.0-or-later
+;;
+;; Copyright (C) 2026 Free Software Foundation, Inc.
+;; See the "HY-COPY" file for license information.
+;;
+;; This file is part of GNU Hyperbole.
+
+;;; Commentary:
+
+;; Test point location relative to string start and end locations.
+
+;;; Code:
+
+;;; ************************************************************************
+;;; Other required Elisp libraries
+;;; ************************************************************************
+
+(require 'cl-lib) ;; For `cl-incf'
+(require 'hypb) ;; For `hypb:in-string-p'
+
+;; Sample use of next function
+;; (debug-in-string "double-quotes" "str")
+;; (debug-in-string "double-with-single" "' st' 'r' ")
+;; (debug-in-string "python-triple-multi-line" "\"\"\"\n str\n\"\"\"" 'python-mode)
+
+;;; ************************************************************************
+;;; Public functions
+;;; ************************************************************************
+
+(defun debug-in-string (test-name str &optional mode)
+ "With TEST-NAME for each char in STR, print results of whether in the string.
+STR, including delimiters, is inserted into a blank buffer for testing.
+With optional major MODE, a function, that mode is enabled prior to testing the string."
+ (interactive sStr to test: \")
+ (with-temp-buffer
+ (when mode (funcall mode))
+ (insert "\"" str "\"")
+ (with-help-window (format "*%s Results*" (capitalize test-name))
+ (prin1 str)
+ (when mode
+ (princ " - ")
+ (princ (cond ((symbolp mode) (symbol-name mode))
+ ((stringp mode) mode))))
+ (terpri)
+ (terpri)
+ (goto-char (point-min))
+ (let ((len (+ (length str) 2))
+ (i 1)
+ hypb-in-str
+ ppss-in-str
+ str-start
+ foll-quote)
+ (while (/= i (point-max))
+ (goto-char i)
+ (setq hypb-in-str (hypb:in-string-p) ;; Hyperbole in-string test
+ ppss-in-str (nth 3 (syntax-ppss)) ;; Emacs in-string test
+ str-start (nth 8 (syntax-ppss)) ;; Char that starts this string, if any
+ foll-quote (nth 5 (syntax-ppss))) ;; t if following a quote char
+ (princ
+ (format "%s Pos %2d, char '%c', in-str hypb=%3S %3S=ppss, str-start=%3S, following-quote=%3S"
+ (if (or (and hypb-in-str ppss-in-str)
+ (and (not hypb-in-str) (not ppss-in-str)))
+ "."
+ "F")
+ i (following-char)
+ hypb-in-str ppss-in-str str-start foll-quote
+ ;; Hyperbole in-string test
+ (hypb:in-string-p)
+ ;; Emacs in-string test; any non-nil value is the
+ ;; character that will terminate the string, or t if the
+ ;; string should be terminated by a generic string
+ ;; delimiter
+ (nth 3 (syntax-ppss))
+ ;; Character address of start of comment or string;
+ ;; nil if not in one
+ (nth 8 (syntax-ppss))
+ ;; t if following a quote char
+ (nth 5 (syntax-ppss))
+ ;; Sixth arg COMMENTSTOP non-nil means stop after the
+ ;; start of a comment. If it is the symbol
+ ;; ‘syntax-table’, stop after the start of a comment or a
+ ;; string, or after end of a comment or a string.
+ ))
+ (terpri)
+ (cl-incf i))))))
+
+
+(provide 'hy-string-tests)
+
+;;; hy-string-tests.el ends here
diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el
index 19f80dba..c219ba5c 100644
--- a/test/hywiki-tests.el
+++ b/test/hywiki-tests.el
@@ -3,7 +3,7 @@
;; Author: Mats Lidell
;;
;; Orig-Date: 18-May-24 at 23:59:48
-;; Last-Mod: 21-Jul-26 at 22:30:31 by Mats Lidell
+;; Last-Mod: 23-Jul-26 at 11:38:53 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;