From bfd0625c9fb11bae29808714dc64d9cce03e7343 Mon Sep 17 00:00:00 2001 From: Max Nikulin Date: Fri, 20 Oct 2023 23:35:16 +0700 Subject: [PATCH 3/3] ox-ascii.el: Allow to export custom links as notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * lisp/ox-ascii.el (org-ascii--describe-links, org-ascii-link): Handle (PATH . DESCRIPTION) values returned by :export property of `org-link-parameters'. It allows to respect `org-ascii-links-to-notes' for custom link types. * testing/lisp/test-ox-ascii.el (test-ox-ascii/link-custom-protocol-cons): New test for the added feature. * lisp/ol-man.el (org-man-export): Allow to export links to man pages as notes at the end of heading. Actually I believe that proper export for man links is man(1), not a URL to a web site, but I am not going to change it in this commit. See the following mailing list thread: Ihor Radchenko to emacs-orgmode… Re: Exporting elisp: and shell: links. Sat, 14 Oct 2023 08:13:35 +0000. https://list.orgmode.org/87wmvp1v0w.fsf@localhost --- lisp/ol-man.el | 2 +- lisp/ox-ascii.el | 29 +++++++++++-- testing/lisp/test-ox-ascii.el | 79 +++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/lisp/ol-man.el b/lisp/ol-man.el index abe79086a..e0c56ed7b 100644 --- a/lisp/ol-man.el +++ b/lisp/ol-man.el @@ -91,7 +91,7 @@ (defun org-man-export (link description backend) ((eq backend 'html) (format "%s" path desc)) ((eq backend 'latex) (format "\\href{%s}{%s}" path desc)) ((eq backend 'texinfo) (format "@uref{%s,%s}" path desc)) - ((eq backend 'ascii) (format "%s (%s)" desc path)) + ((eq backend 'ascii) (cons path desc)) ((eq backend 'md) (format "[%s](%s)" desc path)) (t path)))) diff --git a/lisp/ox-ascii.el b/lisp/ox-ascii.el index 219e6efae..b5407e934 100644 --- a/lisp/ox-ascii.el +++ b/lisp/ox-ascii.el @@ -967,13 +967,26 @@ (defun org-ascii--describe-links (links width info) (org-link-broken nil))))) (setq location (and dest (org-ascii--describe-datum dest info)))))) + ;; Do not add a link already handled by custom export + ;; functions. + ((pcase (org-export-custom-protocol-maybe + link + (and description (org-export-data description info)) + 'ascii + info) + ((pred null)) + ((pred stringp) t) + (`(,(and (or `nil (pred stringp)) path) . + ,(and (or `nil (pred stringp)) desc)) + (setq location (org-string-nw-p path)) + (setq anchor desc) + t) + (_ (error "Link :export returned not cons, or string, or nil: %s" + raw-link)))) ;; Do not add a link that cannot be resolved and doesn't have ;; any description: destination is already visible in the ;; paragraph. ((not description)) - ;; Do not add a link already handled by custom export - ;; functions. - ((org-export-custom-protocol-maybe link anchor 'ascii info) nil) (t (setq location (format "<%s>" raw-link)))) (and location @@ -1608,7 +1621,15 @@ (defun org-ascii-link (link desc info) INFO is a plist holding contextual information." (let ((type (org-element-property :type link))) (cond - ((org-export-custom-protocol-maybe link desc 'ascii info)) + ((pcase (org-export-custom-protocol-maybe link desc 'ascii info) + ((pred null) nil) ; Use fallback. + ((and (pred stringp) str) str) + (`(nil . nil) "") + (`(,(and (or `nil (pred stringp)) custom-path) . + ,(and (or `nil (pred stringp)) custom-desc)) + (org-ascii-link-inline custom-path custom-desc info)) + (_ (error "Link :export returned not cons, or string, or nil: %s" + (org-element-property :raw-link link))))) ((string= type "coderef") (let ((ref (org-element-property :path link))) (format (org-export-get-coderef-format ref desc) diff --git a/testing/lisp/test-ox-ascii.el b/testing/lisp/test-ox-ascii.el index 07def1633..4afe8216f 100644 --- a/testing/lisp/test-ox-ascii.el +++ b/testing/lisp/test-ox-ascii.el @@ -113,6 +113,85 @@ (ert-deftest test-ox-ascii/link-custom-protocol-string () inline).\n")))) (test-ox-ascii--restore-syntax))) +(ert-deftest test-ox-ascii/link-custom-protocol-cons () + "Test link custom protocol optional note (cons return value)." + (unwind-protect + (let ((org-link-parameters)) + (org-link-set-parameters + "tstcons" + :export (lambda (path descr _backend _info) + (cons (concat "excons-" path) descr))) + ;; As notes. + (let ((org-ascii-links-to-notes t)) + (should ; With description. + (string-equal + (org-export-string-as + "Link [[tstcons:path-descr][with descr[iption]\u200b]] as note." + 'ascii t) + "Link [with descr[iption]\u200b] as note. +\n +[with descr[iption]\u200b] excons-path-descr\n")) + (should ; No description. + (string-equal + (org-export-string-as + "Link without description (note)." + 'ascii t) + "Link excons-path-no-descr without description (note).\n"))) + ;; Inline. + (let ((org-ascii-links-to-notes nil)) + (should ; With description. + (string-equal + (org-export-string-as + "Inline link [[tstcons:path-descr][with description]]." + 'ascii t) + "Inline link with description (excons-path-descr).\n")) + (should ; No description. + (string-equal + (org-export-string-as + "Inline link [[tstcons:path-no-descr]] without description." + 'ascii t) + "Inline link excons-path-no-descr without description.\n"))) + ;; Force parenthesis. + (let ((org-link-parameters)) + (org-link-set-parameters + "brcons" + :export (lambda (path descr _backend _info) + (cons (format "(exbr-%s)" path) + (and descr (format "[%s]" descr))))) + (let ((org-ascii-links-to-notes t)) + (should + (string-equal + (org-export-string-as + "Link [[brcons:path-descr][with brackets]] as note." + 'ascii t) + "Link [with brackets] as note. +\n +[with brackets] (exbr-path-descr)\n"))) + ;; Inline. + (let ((org-ascii-links-to-notes nil)) + (should + (string-equal + (org-export-string-as + "Link [[brcons:path-descr][with brackets]] inline." + 'ascii t) + "Link [with brackets] (exbr-path-descr) inline.\n")))) + ;; Error. + (org-link-set-parameters + "tsterr" + :export (lambda (path descr _backend _info) + (list (concat "ex-error! " path) descr "extra arg"))) + (let* ((err (should-error + (org-export-string-as + "Signals [[tsterr:invalid :export][aaa]] error." + 'ascii t) + :type 'error)) + (err-text (cadr err))) + (should-not (unless (and (stringp err-text) + (string-match-p "\\`Link :export returned not.*" + err-text)) + err)))) + (test-ox-ascii--restore-syntax))) + (ert-deftest test-ox-ascii/list () "Test lists." ;; Number counter. -- 2.39.2