From 1e9b31174ab4cfb2edb73f23aa1a3ec86943ba42 Mon Sep 17 00:00:00 2001 From: Mekeor Melire Date: Mon, 4 Dec 2023 16:37:37 +0100 Subject: [PATCH] * lisp/info.el (Info-url-alist): New option mapping manuals to URLs. --- ChangeLog.4 | 8 +++++ etc/NEWS | 9 +++++ lisp/info.el | 100 ++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 96 insertions(+), 21 deletions(-) diff --git a/ChangeLog.4 b/ChangeLog.4 index 24afabdbbb1..0aabd9f52bb 100644 --- a/ChangeLog.4 +++ b/ChangeLog.4 @@ -1,3 +1,11 @@ +2023-12-08 Mekeor Melire + + Support online-browsing all Emacs-contained manuals or any other. + + * lisp/info.el (Info-url-alist): New defcustom that maps + manual-names to URL-specifications. + (Info-url-for-node): Use it. + 2023-10-16 Po Lu Correctly register focus events concomitant with alpha changes diff --git a/etc/NEWS b/etc/NEWS index 29f4e5c0b66..4730cc3a351 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -356,6 +356,15 @@ respectively, in addition to the existing translations 'C-x 8 / e' and * Changes in Specialized Modes and Packages in Emacs 30.1 +** Info + +--- +*** New user option 'Info-url-alist'. +This user option associates manual-names with URLs. It affects the +'Info-goto-node-web' command. By default, associations for all +Emacs-included manuals are set. Further associations can be added for +arbitrary info manuals. + +++ ** New command 'lldb'. Run the LLDB debugger, analogous to the 'gud-gdb' command. Note that diff --git a/lisp/info.el b/lisp/info.el index 51e9eb72edf..c0e342a62d6 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -213,6 +213,52 @@ Info-additional-directory-list These directories are searched after those in `Info-directory-list'." :type '(repeat directory)) +(defcustom Info-url-alist + '((("auth" "autotype" "bovine" "calc" "ccmode" "cl" "dbus" "dired-x" + "ebrowse" "ede" "ediff" "edt" "efaq" "efaq-w32" "eglot" "eieio" + "eintr" "elisp" "emacs" "emacs-gnutls" "emacs-mime" "epa" "erc" + "ert" "eshell" "eudc" "eww" "flymake" "forms" "gnus" + "htmlfontify" "idlwave" "ido" "info" "mairix-el" "message" + "mh-e" "modus-themes" "newsticker" "nxml-mode" "octave-mode" + "org" "pcl-cvs" "pgg" "rcirc" "reftex" "remember" "sasl" "sc" + "semantic" "ses" "sieve" "smtpmail" "speedbar" "srecode" + "todo-mode" "tramp" "transient" "url" "use-package" "vhdl-mode" + "vip" "viper" "vtable" "widget" "wisent" "woman") . + "https://www.gnu.org/software/emacs/manual/html_node/%m/%e")) + "Alist telling `Info-mode' where manuals are accessible online. + +Each element of this list should match the pattern (MANUALS +. URL-SPEC). MANUALS represents the name of one or many manuals. +It can either be a string or a list of strings. URL-SPEC can be +a string in which the substring \"%m\" will be expanded to the +manual-name, \"%n\" to the node-name, and \"%e\" to the +URL-encoded node-name with a `.html' suffix. (The URL-encoding +of the node-name mimics GNU Texinfo, as documented at info +node `(texinfo)HTML Xref Node Name Expansion'.) Alternatively, +URL-SPEC can be a function which is given manual-name, node-name +and URL-encoded node-name as arguments, and is expected to return +the corresponding URL as string. + +This variable particularly affects the command +`Info-goto-node-web', which see. + +The default value of this variable refers to the official, +HTTPS-accessible HTML-representations of all manuals that Emacs +includes. These URLs refer to the most recently released version +of Emacs, disregarding the version of the running Emacs. In +other words, the content of your local info node and the +associated online node may differ. The resource represented by +the generated URL may even be not found by the gnu.org server." + :type '(alist + :tag "Mapping from manual-name(s) to URL-specification" + :key-type (choice + (string :tag "A single manual-name") + (repeat :tag "List of manual-names" string)) + :value-type (choice + (string :tag "URL-specification string") + (function + :tag "URL-specification function")))) + (defcustom Info-scroll-prefer-subnodes nil "If non-nil, \\\\[Info-scroll-up] in a menu visits subnodes. @@ -1807,33 +1853,45 @@ Info-goto-node-web (Info-url-for-node (format "(%s)%s" filename node))))) (defun Info-url-for-node (node) - "Return a URL for NODE, a node in the GNU Emacs or Elisp manual. -NODE should be a string on the form \"(manual)Node\". Only emacs -and elisp manuals are supported." + "Return a URL for NODE. NODE should be a string of the form +\"(manual)Node\"." (unless (string-match "\\`(\\(.+\\))\\(.+\\)\\'" node) - (error "Invalid node name %s" node)) - (let ((manual (match-string 1 node)) - (node (match-string 2 node))) - (unless (member manual '("emacs" "elisp")) - (error "Only emacs/elisp manuals are supported")) - ;; Encode a bunch of characters the way that makeinfo does. - (setq node - (mapconcat (lambda (ch) - (if (or (< ch 32) ; ^@^A-^Z^[^\^]^^^- + (error "Invalid node-name %s" node)) + ;; use `if-let*' instead of `let*' so we check if an association was + ;; found. + (if-let* ((manual (match-string 1 node)) + (node (match-string 2 node)) + (association (seq-find + (lambda (pair) + (seq-contains (ensure-list (car pair)) + manual #'string-equal-ignore-case)) + Info-url-alist)) + (url-spec (cdr association)) + (encoded-node + ;; Reproduce GNU Texinfo's way of URL-encoding. + ;; (info "(texinfo) HTML Xref Node Name Expansion") + (if (equal node "Top") + "" + (url-hexify-string + (string-replace " " "-" + (mapconcat + (lambda (ch) + (if (or (< ch 32) ; ^@^A-^Z^[^\^]^^^- (<= 33 ch 47) ; !"#$%&'()*+,-./ (<= 58 ch 64) ; :;<=>?@ (<= 91 ch 96) ; [\]_` (<= 123 ch 127)) ; {|}~ DEL (format "_00%x" ch) - (char-to-string ch))) - node - "")) - (concat "https://www.gnu.org/software/emacs/manual/html_node/" - manual "/" - (and (not (equal node "Top")) - (concat - (url-hexify-string (string-replace " " "-" node)) - ".html"))))) + (char-to-string ch))) + node "")))))) + (cond + ((stringp url-spec) + (format-spec url-spec + `((?m . ,manual) (?n . ,node) (?e . ,encoded-node)))) + ((functionp url-spec) + (funcall url-spec manual node encoded-node)) + (t (error "URL-specification neither string nor function"))) + (error "No URL-specification associated with manual-name `%s'"))) (defvar Info-read-node-completion-table) -- 2.41.0