emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Max Nikulin <manikulin@gmail.com>
To: emacs-orgmode@gnu.org
Cc: emacs-orgmode@gnu.org
Subject: [PATCH] ol-info: Enable :insert-description feature
Date: Sat, 30 Jul 2022 19:34:54 +0700	[thread overview]
Message-ID: <8bbccdb4-52f4-b9b5-eb10-252bb15108ec@gmail.com> (raw)
In-Reply-To: <871qu3rpt9.fsf@localhost>

[-- Attachment #1: Type: text/plain, Size: 1536 bytes --]

On 30/07/2022 15:02, Ihor Radchenko wrote:
> 
> Hugo Heagren writes:
> 
>>> The rx-to-string call may still suffer from the described edge case.
>>
>> Yes, I think this is a good idea.
>>
>>> (and all-prefixes ...)
>>
>> I'm not sure what you mean, but I don't think it will work.
> 
> I mean
> 
> (and ,all-prefixes (rx-to-string `(: string-start (submatch (or (and ,@all-prefixes))) ":")))

I agree that it is better than the trick with test, but, I think, it is 
not critical taking into account version of the patch set. I do not see 
any issues that really prevent committing of changes. This time tests 
pass on my side.

When committing the current version or if you decided to prepare a new 
one, please, fix the name of the test. Ihor committed my patch to run ol 
tests, the variant that renames test instead of adjustment of selector.

diff --git a/testing/lisp/test-ol.el b/testing/lisp/test-ol.el
index 5f2cca538..6802f0333 100644
--- a/testing/lisp/test-ol.el
+++ b/testing/lisp/test-ol.el
@@ -673,7 +673,7 @@ API in `org-link-parameters'.  Used in test
  `:insert-description' is a function symbol."
    "foobar-from-function")

-(ert-deftest test-ol/insert-link-insert-description ()
+(ert-deftest test-org-link/insert-link-insert-description ()
    "Test `:insert-description' parameter handling."
    ;; String case.
    (should

To get impression of the new feature in action, I modified ol-info.el. 
First patch does not depend on :insert-description and might be useful 
per se. Second one just enables the feature.

[-- Attachment #2: 0001-ol-info-New-function-to-generate-description.patch --]
[-- Type: text/x-patch, Size: 9053 bytes --]

From 7d46a872ea653c3a64522463fe3f35412ac6753e Mon Sep 17 00:00:00 2001
From: Max Nikulin <manikulin@gmail.com>
Date: Sat, 30 Jul 2022 19:13:01 +0700
Subject: [PATCH 1/2] ol-info: New function to generate description

* lisp/ol-info.el (org-info-link-file-node): New helper to parse info
link info file (manual) name and node.
(org-info-description-as-command): New function to create description
for info links that may executed to view a manual.
(org-info-follow-link, org-info-export): Use `org-info-link-file-node'.
* testing/lisp/test-ol-info.el (test-org-link-info/link-file-node)
(test-org-link-info/description-as-command): New file for tests of new
functions `org-info-link-file-node', `org-info-description-as-command'.

Prepare to :insert-description new feature of `org-link'.
---
 lisp/ol-info.el              | 80 ++++++++++++++++++++++++++-------
 testing/lisp/test-ol-info.el | 87 ++++++++++++++++++++++++++++++++++++
 2 files changed, 150 insertions(+), 17 deletions(-)
 create mode 100644 testing/lisp/test-ol-info.el

diff --git a/lisp/ol-info.el b/lisp/ol-info.el
index dc5f6d5ba..008b4d34f 100644
--- a/lisp/ol-info.el
+++ b/lisp/ol-info.el
@@ -63,24 +63,70 @@
   "Follow an Info file and node link specified by PATH."
   (org-info-follow-link path))
 
+(defun org-info-link-file-node (link)
+  "Extract file name and node from info LINK.
+
+Return list containing file name and node name or \"Top\".
+Components may be separated by \"::\" or by \"#\"."
+  (and
+   link
+   (or
+    (string-match "\\`\\([^:]*:\\)?\\(.*\\)\\(?:#\\|::\\)\\(.*\\)?\\'" link)
+    (string-match "\\`\\([^:]*:\\)?\\(.*\\)\\'" link))
+   (let ((scheme (match-string 1 link))
+         (file (match-string 2 link))
+         (node (match-string 3 link)))
+     (and
+      (or (not scheme) (string-equal "info:" scheme))
+      (org-string-nw-p file)
+      (list file (or (org-string-nw-p node) "Top"))))))
+
+(defun org-info-description-as-command (link desc)
+  "Info link description that can be pasted as command.
+
+For the folloing LINK
+
+    \"info:elisp::Non-ASCII in Strings\"
+
+the result is
+
+    info \"(elisp) Non-ASCII in Strings\"
+
+that may be executed as a shell command or evaluated by
+\\[eval-expression] (wrapped with parenthesis) to read the manual
+in Emacs.
+
+Calling convention is similar to `org-link-make-description-function'.
+DESC has higher priority and returned when it is not nil.
+If LINK is not an info link then DESC is returned."
+  (or (org-string-nw-p desc)
+      (let* ((file-node (org-info-link-file-node link))
+             (file (car file-node))
+             (node (cadr file-node)))
+        (cond
+         ((and node (not (string-equal "Top" node)))
+          (format "info \"(%s) %s\"" file node))
+         (file (format "info %s" file))
+         (t desc)))))
+
 
 (defun org-info-follow-link (name)
   "Follow an Info file and node link specified by NAME."
-  (if (or (string-match "\\(.*\\)\\(?:#\\|::\\)\\(.*\\)" name)
-          (string-match "\\(.*\\)" name))
-      (let ((filename (match-string 1 name))
-	    (nodename-or-index (or (match-string 2 name) "Top")))
-	(require 'info)
-	;; If nodename-or-index is invalid node name, then look it up
-	;; in the index.
-	(condition-case nil
-	    (Info-find-node filename nodename-or-index)
-	  (user-error (Info-find-node filename "Top")
-		      (condition-case nil
-			  (Info-index nodename-or-index)
-			(user-error "Could not find '%s' node or index entry"
-				    nodename-or-index)))))
-    (user-error "Could not open: %s" name)))
+  (let* ((file-node (org-info-link-file-node name))
+         (filename (car file-node))
+         (nodename-or-index (cadr file-node)))
+    (if (not filename)
+        (user-error "Could not open: %s" name)
+      (require 'info)
+      ;; If nodename-or-index is invalid node name, then look it up
+      ;; in the index.
+      (condition-case nil
+          (Info-find-node filename nodename-or-index)
+        (user-error (Info-find-node filename "Top")
+                    (condition-case nil
+                        (Info-index nodename-or-index)
+                      (user-error "Could not find '%s' node or index entry"
+                                  nodename-or-index)))))))
 
 (defconst org-info-emacs-documents
   '("ada-mode" "auth" "autotype" "bovine" "calc" "ccmode" "cl" "dbus" "dired-x"
@@ -129,9 +175,9 @@ See `org-info-emacs-documents' and `org-info-other-documents' for details."
 (defun org-info-export (path desc format)
   "Export an info link.
 See `org-link-parameters' for details about PATH, DESC and FORMAT."
-  (let* ((parts (split-string path "#\\|::"))
+  (let* ((parts (org-info-link-file-node path))
 	 (manual (car parts))
-	 (node (or (nth 1 parts) "Top")))
+	 (node (nth 1 parts)))
     (pcase format
       (`html
        (format "<a href=\"%s#%s\">%s</a>"
diff --git a/testing/lisp/test-ol-info.el b/testing/lisp/test-ol-info.el
new file mode 100644
index 000000000..aa5234260
--- /dev/null
+++ b/testing/lisp/test-ol-info.el
@@ -0,0 +1,87 @@
+;;; test-ol-info.el --- tests for ol-info.el                        -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author:  Max Nikulin <manikulin@gmail.com>
+;; Keywords: org, texinfo
+
+;; 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 3 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, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Test some functions from ol-info.el.
+
+;;; Code:
+
+(unless (featurep 'ol-info)
+  (signal 'missing-test-dependency "Support for info links"))
+
+(ert-deftest test-org-link-info/link-file-node ()
+  "Test parse info links by `org-info-link-file-node'."
+  (should (equal '("success" "Double Colon Separator")
+                 (org-info-link-file-node "success::Double Colon Separator")))
+  (should (equal '("success" "Hash Separator")
+                 (org-info-link-file-node "success#Hash Separator")))
+  (should (equal '("nodeless" "Top")
+                 (org-info-link-file-node "nodeless")))
+  (should (equal '("trailing-hash" "Top")
+                 (org-info-link-file-node "trailing-hash#")))
+  (should (equal '("trailing-double-colon" "Top")
+                 (org-info-link-file-node "trailing-double-colon")))
+  (should (equal '("with-scheme" "Double Colon Separator")
+                 (org-info-link-file-node "info:with-scheme::Double Colon Separator")))
+  (should (equal '("with-scheme" "Hash Separator")
+                 (org-info-link-file-node "info:with-scheme#Hash Separator")))
+  (should (equal '("scheme-and-file" "Top")
+                 (org-info-link-file-node "info:scheme-and-file")))
+  (should (equal '("scheme-file-hash" "Top")
+                 (org-info-link-file-node "info:scheme-file-hash#")))
+  (should (equal '("scheme-file-double-colon" "Top")
+                 (org-info-link-file-node "info:scheme-file-double-colon")))
+  (should (eq nil (org-info-link-file-node nil)))
+  (should (eq nil (org-info-link-file-node "Info:broken#Wrong scheme case")))
+  (should (eq nil (org-info-link-file-node "http:broken::Not info scheme"))))
+
+(ert-deftest test-org-link-info/description-as-command ()
+  "Test `org-info-description-as-command'."
+  (let ((cases
+         '(("info file" "file")
+           ("info strip-top" "strip-top#Top")
+           ("info strip-top-hash" "info:strip-top-hash#Top")
+           ("info strip-top-double-colon" "strip-top-double-colon::Top")
+           ("info \"(pass) Hash\"" "pass#Hash")
+           ("info \"(pass) Double Colon\"" "info:pass#Double Colon")
+           (nil nil)
+           (nil "https://wrong.scheme"))))
+    (dolist (expectation-input cases)
+      (let ((expectation (car expectation-input))
+            (input (cadr expectation-input)))
+        (should (equal
+                 expectation
+                 (org-info-description-as-command input nil))))))
+  (let ((cases
+         '(("Override link" "ignored#Link" "Override link")
+           ("Fallback description" "http://not.info/link" "Fallback description")
+           ("Link is nil" nil "Link is nil")
+           (nil nil nil))))
+        (dolist (expectation-input-desc cases)
+      (let ((expectation (car expectation-input-desc))
+            (input (cadr expectation-input-desc))
+            (desc (nth 2 expectation-input-desc)))
+        (should (equal
+                 expectation
+                 (org-info-description-as-command input desc)))))))
+
+(provide 'test-ol-info)
+;;; test-ol-info.el ends here
-- 
2.25.1


[-- Attachment #3: 0002-ol-info-Enable-insert-description-feature.patch --]
[-- Type: text/x-patch, Size: 743 bytes --]

From f27a3b5bc01cdb915114797347f7b3491d8101dd Mon Sep 17 00:00:00 2001
From: Max Nikulin <manikulin@gmail.com>
Date: Sat, 30 Jul 2022 19:16:42 +0700
Subject: [PATCH 2/2] ol-info: Enable :insert-description feature

---
 lisp/ol-info.el | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lisp/ol-info.el b/lisp/ol-info.el
index 008b4d34f..83e08ae18 100644
--- a/lisp/ol-info.el
+++ b/lisp/ol-info.el
@@ -43,7 +43,8 @@
 (org-link-set-parameters "info"
 			 :follow #'org-info-open
 			 :export #'org-info-export
-			 :store #'org-info-store-link)
+			 :store #'org-info-store-link
+                         :insert-description #'org-info-description-as-command)
 
 ;; Implementation
 (defun org-info-store-link ()
-- 
2.25.1


  reply	other threads:[~2022-07-30 12:35 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-28 23:15 ol.el: add description format parameter to org-link-parameters Hugo Heagren
2022-03-28 23:15 ` [PATCH] " Hugo Heagren
2022-04-04  9:49   ` Ihor Radchenko
2022-04-05 19:29     ` [PATCH v2] " Hugo Heagren
2022-04-07  5:13       ` Ihor Radchenko
2022-06-21 12:03         ` [PATCH v3] " Hugo Heagren
2022-06-21 13:41           ` Robert Pluim
2022-07-07 19:57             ` [PATCH v4] " Hugo Heagren
2022-07-09  3:31               ` Ihor Radchenko
2022-07-14 13:08                 ` [PATCH v5] " Hugo Heagren
2022-07-16  9:09                   ` Ihor Radchenko
2022-07-16 21:20                     ` Hugo Heagren
2022-07-17  6:11                       ` Max Nikulin
2022-07-17 10:27                         ` Ihor Radchenko
2022-07-17 10:18                       ` Ihor Radchenko
2022-07-17 20:59                         ` [PATCH v6] " Hugo Heagren
2022-07-18 10:55                           ` Max Nikulin
2022-07-23  7:48                             ` [PATCH v7] " Hugo Heagren
2022-07-23  7:59                               ` Max Nikulin
2022-07-23 13:06                                 ` Ihor Radchenko
2022-07-23 15:46                                   ` Max Nikulin
2022-07-24 10:34                                   ` Max Nikulin
2022-07-24 13:15                                     ` Ihor Radchenko
2022-07-25 11:55                                       ` [PATCH v8] " Hugo Heagren
2022-07-29 12:54                                         ` Max Nikulin
2022-07-29 19:05                                           ` [PATCH v9] " Hugo Heagren
2022-07-30  6:29                                             ` Ihor Radchenko
     [not found]                                               ` <87tu6zf2o1.fsf@heagren.com>
2022-07-30  8:02                                                 ` Ihor Radchenko
2022-07-30 12:34                                                   ` Max Nikulin [this message]
2022-08-06  7:00                                                     ` [PATCH] ol-info: Enable :insert-description feature Ihor Radchenko
2022-08-14 16:41                                                       ` [PATCH v2] ol-info: Define :insert-description function Max Nikulin
2022-08-19  4:28                                                         ` Ihor Radchenko
2022-08-19 12:26                                                           ` Max Nikulin
2022-08-20  7:29                                                             ` Ihor Radchenko
2022-08-21 14:49                                                               ` Max Nikulin
2022-08-22  4:10                                                                 ` Ihor Radchenko
2022-08-24 14:37                                                                   ` [PATCH v3] " Max Nikulin
2022-08-26 13:15                                                                     ` Ihor Radchenko
2022-09-04 15:05                                                       ` [PATCH] ol-info: Enable :insert-description feature Max Nikulin
2022-09-05  6:36                                                         ` Ihor Radchenko
2022-08-06  6:06                                             ` [PATCH v9] ol.el: add description format parameter to org-link-parameters Ihor Radchenko
2022-07-29  1:47                               ` [PATCH v7] " Ihor Radchenko
2022-07-29  7:05                                 ` Bastien Guerry
2022-07-10 10:26               ` [PATCH v4] " Max Nikulin
2022-06-21 15:01           ` [PATCH v3] " Max Nikulin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8bbccdb4-52f4-b9b5-eb10-252bb15108ec@gmail.com \
    --to=manikulin@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).