emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: "Rudolf Adamkovič" <rudolf@adamkovic.org>
To: emacs-orgmode@gnu.org
Subject: Re: Texinfo: Custom navigation and links in headings
Date: Fri, 23 Aug 2024 14:45:27 +0200	[thread overview]
Message-ID: <m2v7zrh0go.fsf@adamkovic.org> (raw)
In-Reply-To: <m2ed6fbtsa.fsf@adamkovic.org>

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

Rudolf Adamkovič <rudolf@adamkovic.org> writes:

> I found a bug where
>
>     the Top node ignores ALT_NAVIGATION.
>
> This is because the node
>
>     is treated separately in `ox-texinfo.el'.
>
> I will fix the bug it today.

And fixed!  Please see the attached patches.

(I also fixed commit messages, indentation, etc.)

The patches are

    ready for code review

now.

Thank you!

Rudy


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-texinfo-Add-support-for-custom-navigation-hierarc.patch --]
[-- Type: text/x-patch, Size: 12055 bytes --]

From ba13b7a50d515db99a5cdd0dea19ea98b76d68b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rudolf=20Adamkovi=C4=8D?= <rudolf@adamkovic.org>
Date: Thu, 22 Aug 2024 12:27:01 +0200
Subject: [PATCH 1/2] ox-texinfo: Add support for custom navigation hierarchies

* doc/org-manual.org (Headings and sectioning structure): Describe the
new feature in detail.
* etc/ORG-NEWS (Texinfo exports can have custom navigation
hierarchies): Inform end users about the new feature.
* lisp/org.el (org-default-properties): Offer the `ALT_TITLE' and
`ALT_NAVIGATION' properties for completion.
* lisp/ox-texinfo.el (org-texinfo-headline, org-texinfo-template): Use
the `ALT_NAVIGATION' property when generating Texinfo notes to set the
Next, Previous, and Up pointers of the relevant Texinfo node.
(org-texinfo--match-definition, org-texinfo-item): Fix indentation.
* testing/lisp/test-ox-texinfo.el (test-ox-texinfo/alt-title,
test-ox-texinfo/alt-navigation/all-directions,
test-ox-texinfo/alt-navigation/one-direction,
test-ox-texinfo/alt-navigation/no-directions,
test-ox-texinfo/alt-navigation/with-alt-title,
test-ox-texinfo/alt-navigation/top/default,
test-ox-texinfo/alt-navigation/top/default): Test the new feature to
avoid regressions in the future.
---
 doc/org-manual.org              |  23 ++++++
 etc/ORG-NEWS                    |   7 ++
 lisp/org.el                     |   3 +-
 lisp/ox-texinfo.el              |  21 +++--
 testing/lisp/test-ox-texinfo.el | 133 ++++++++++++++++++++++++++++++++
 5 files changed, 181 insertions(+), 6 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index 9365c66b1..9b53c13c1 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -15999,6 +15999,29 @@ the node in which a reader enters an Info manual.  As such, it is
 expected not to appear in printed output generated from the =.texi=
 file.  See [[info:texinfo::The Top Node]], for more information.
 
+#+cindex: @samp{ALT_NAVIGATION}, property
+By default, Texinfo automatically sets the /Next/, /Previous/, and
+/Up/ pointers, reflecting the hierarchy of your document.  If you want
+it to reflect a different hierarchy, or no hierarchy at all, set the
+=ALT_NAVIGATION= property to a list of at most 3 titles, separated by
+commas, to be used for the /Next/, /Previous/, and /Up/ pointers,
+respectively.  For example:
+
+#+begin_example
+,* Mathematical Logic
+  :PROPERTIES:
+  :ALT_TITLE: Logic
+  :END:
+
+,* Proposition
+  :PROPERTIES:
+  :ALT_NAVIGATION: ,, Logic
+  :END:
+
+  - /Next/ and /Previous/ disabled.
+  - /Up/ leads to [[Mathematical Logic]].
+#+end_example
+
 *** Indices
 :PROPERTIES:
 :DESCRIPTION: Creating indices.
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 392788055..25dd3ae49 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -77,6 +77,13 @@ You can now create links to =shortdoc= documentation groups for Emacs
 Lisp functions (see =M-x shortdoc-display-group=).  Requires Emacs 28
 or newer.
 
+*** Texinfo exports can have custom navigation hierarchies
+
+You can now alter the Texinfo navigation hierarchy by specifying the
+/Next/, /Previous/, and /Up/ pointers in the =ALT_NAVIGATION=
+property.  For more information, see "13.14.6 Headings and sectioning
+structure" section of the Org manual.
+
 ** New and changed options
 
 # Chanes deadling with changing default values of customizations,
diff --git a/lisp/org.el b/lisp/org.el
index d5c1dcb35..dcd05571e 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -12691,7 +12691,8 @@ but in some other way.")
     "EXPORT_TITLE" "EXPORT_AUTHOR" "EXPORT_DATE" "UNNUMBERED"
     "ORDERED" "NOBLOCKING" "COOKIE_DATA" "LOG_INTO_DRAWER" "REPEAT_TO_STATE"
     "CLOCK_MODELINE_TOTAL" "STYLE" "HTML_CONTAINER_CLASS"
-    "ORG-IMAGE-ACTUAL-WIDTH")
+    "ORG-IMAGE-ACTUAL-WIDTH"
+    "ALT_TITLE" "ALT_NAVIGATION")
   "Some properties that are used by Org mode for various purposes.
 Being in this list makes sure that they are offered for completion.")
 
diff --git a/lisp/ox-texinfo.el b/lisp/ox-texinfo.el
index 6adee9fca..a396d93d3 100644
--- a/lisp/ox-texinfo.el
+++ b/lisp/ox-texinfo.el
@@ -652,7 +652,7 @@ The car is the command and the cdr is its arguments."
 	 (string-match org-texinfo--definition-command-regexp tag)
 	 (pcase-let*
 	     ((cmd (car (rassoc (match-string-no-properties 1 tag)
-				 org-texinfo--definition-command-alist)))
+				org-texinfo--definition-command-alist)))
 	      (`(,cmd ,category)
 	       (and cmd (save-match-data (split-string cmd " "))))
 	      (args (match-string-no-properties 2 tag)))
@@ -799,7 +799,7 @@ holding export options."
 		   (org-export-data copying info))))
      (let* ((dircat (or (plist-get info :texinfo-dircat) "Misc"))
 	    (file (or (org-strip-quotes (plist-get info :texinfo-filename))
-		    (plist-get info :output-file)))
+		      (plist-get info :output-file)))
 	    (file (if file (file-name-sans-extension file)))
 	    (dn (or (plist-get info :texinfo-dirname)
 	            (plist-get info :texinfo-dirtitle))) ;Obsolete name.
@@ -875,7 +875,15 @@ holding export options."
      ;; Configure Top Node when not for TeX.  Also include contents
      ;; from the first section of the document.
      "@ifnottex\n"
-     "@node Top\n"
+     ;; Top node.
+     "@node Top"
+     (if-let ((top-navigation
+               (org-element-map (plist-get info :parse-tree) 'org-data
+                 (lambda (data)
+                   (org-element-property :ALT_NAVIGATION data))
+                 info t)))
+         (concat ", " top-navigation))
+     "\n"
      (format "@top %s\n" title)
      (let* ((first-section
 	     (org-element-map (plist-get info :parse-tree) 'section
@@ -1102,6 +1110,7 @@ holding contextual information."
 	   (full-text
 	    (funcall (plist-get info :texinfo-format-headline-function)
 		     todo todo-type priority text tags))
+           (navigation (org-element-property :ALT_NAVIGATION headline))
 	   (contents
 	    (concat "\n"
 		    (if (org-string-nw-p contents) (concat "\n" contents) "")
@@ -1118,7 +1127,9 @@ holding contextual information."
 	(concat
 	 ;; Even if HEADLINE is using @subheading and al., leave an
 	 ;; anchor so cross-references in the Org document still work.
-	 (format (if notoc? "@anchor{%s}\n" "@node %s\n") node)
+	 (format (if notoc? "@anchor{%s}" "@node %s") node)
+         (if navigation (concat ", " navigation) "")
+         "\n"
 	 (format command full-text)
 	 contents))))))
 
@@ -1189,7 +1200,7 @@ contextual information."
          (compact (and (eq (org-element-property :type plain-list) 'descriptive)
                        (or (plist-get info :texinfo-compact-itemx)
                            (org-not-nil (org-export-read-attribute
-                                       :attr_texinfo plain-list :compact)))))
+                                         :attr_texinfo plain-list :compact)))))
          (previous-item nil))
     (when (and compact
                (org-export-get-next-element item info)
diff --git a/testing/lisp/test-ox-texinfo.el b/testing/lisp/test-ox-texinfo.el
index b16a344e7..fe931baa4 100644
--- a/testing/lisp/test-ox-texinfo.el
+++ b/testing/lisp/test-ox-texinfo.el
@@ -345,5 +345,138 @@ body
        (should-not (org-element-contents section))
        (should (eq first-heading (org-element-parent section)))))))
 
+\f
+;;; Alternative title and navigation
+
+(ert-deftest test-ox-texinfo/alt-title ()
+  "Test alternative titles."
+  (should
+   (org-test-with-temp-text
+       (string-join
+        (list "* Title 1"
+              ":PROPERTIES:"
+              ":ALT_TITLE: Title 2"
+              ":END:")
+        "\n")
+     (let ((export-buffer "*Test Texinfo Export*")
+           (org-export-show-temporary-export-buffer nil))
+       (org-export-to-buffer 'texinfo export-buffer
+         nil nil nil nil nil
+         #'texinfo-mode)
+       (with-current-buffer export-buffer
+         (goto-char (point-min))
+         (search-forward "@node Title 2"))))))
+
+(ert-deftest test-ox-texinfo/alt-navigation/all-directions ()
+  "Test alternative navigation in all directions."
+  (should
+   (org-test-with-temp-text
+       (string-join
+        (list "* Title"
+              ":PROPERTIES:"
+              ":ALT_NAVIGATION: Next, Previous, Up"
+              ":END:")
+        "\n")
+     (let ((export-buffer "*Test Texinfo Export*")
+           (org-export-show-temporary-export-buffer nil))
+       (org-export-to-buffer 'texinfo export-buffer
+         nil nil nil nil nil
+         #'texinfo-mode)
+       (with-current-buffer export-buffer
+         (goto-char (point-min))
+         (search-forward "@node Title, Next, Previous, Up"))))))
+
+(ert-deftest test-ox-texinfo/alt-navigation/one-direction ()
+  "Test alternative navigation in only one direction."
+  (should
+   (org-test-with-temp-text
+       (string-join
+        (list "* Title"
+              ":PROPERTIES:"
+              ":ALT_NAVIGATION: ,, Up"
+              ":END:")
+        "\n")
+     (let ((export-buffer "*Test Texinfo Export*")
+           (org-export-show-temporary-export-buffer nil))
+       (org-export-to-buffer 'texinfo export-buffer
+         nil nil nil nil nil
+         #'texinfo-mode)
+       (with-current-buffer export-buffer
+         (goto-char (point-min))
+         (search-forward "@node Title, ,, Up"))))))
+
+(ert-deftest test-ox-texinfo/alt-navigation/no-directions ()
+  "Test alternative navigation with all directions disabled."
+  (should
+   (org-test-with-temp-text
+       (string-join
+        (list "* Title"
+              ":PROPERTIES:"
+              ":ALT_NAVIGATION: ,,"
+              ":END:")
+        "\n")
+     (let ((export-buffer "*Test Texinfo Export*")
+           (org-export-show-temporary-export-buffer nil))
+       (org-export-to-buffer 'texinfo export-buffer
+         nil nil nil nil nil
+         #'texinfo-mode)
+       (with-current-buffer export-buffer
+         (goto-char (point-min))
+         (search-forward "@node Title, ,,"))))))
+
+(ert-deftest test-ox-texinfo/alt-navigation/with-alt-title ()
+  "Test alternative navigation combined with alternative titles."
+  (should
+   (org-test-with-temp-text
+       (string-join
+        (list "* Title 1"
+              ":PROPERTIES:"
+              ":ALT_TITLE: Title 2"
+              ":ALT_NAVIGATION: Next, Previous, Up"
+              ":END:")
+        "\n")
+     (let ((export-buffer "*Test Texinfo Export*")
+           (org-export-show-temporary-export-buffer nil))
+       (org-export-to-buffer 'texinfo export-buffer
+         nil nil nil nil nil
+         #'texinfo-mode)
+       (with-current-buffer export-buffer
+         (goto-char (point-min))
+         (search-forward "@node Title 2, Next, Previous, Up"))))))
+
+
+(ert-deftest test-ox-texinfo/alt-navigation/top-node/default ()
+  "Test alternative navigation when not set at the top level."
+  (should
+   (org-test-with-temp-text "Hello world!"
+     (let ((export-buffer "*Test Texinfo Export*")
+           (org-export-show-temporary-export-buffer nil))
+       (org-export-to-buffer 'texinfo export-buffer
+         nil nil nil nil nil
+         #'texinfo-mode)
+       (with-current-buffer export-buffer
+         (goto-char (point-min))
+         (re-search-forward "^@node Top$"))))))
+
+(ert-deftest test-ox-texinfo/alt-navigation/top-node/custom ()
+  "Test alternative navigation when set at the top level."
+  (should
+   (org-test-with-temp-text
+       (string-join
+        (list ":PROPERTIES:"
+              ":ALT_NAVIGATION: Next, Previous, Up"
+              ":END:"
+              "#+TITLE: Title"
+              "* Headline")
+        "\n")
+     (let ((export-buffer "*Test Texinfo Export*")
+           (org-export-show-temporary-export-buffer nil))
+       (org-export-to-buffer 'texinfo export-buffer
+         nil nil nil nil nil
+         #'texinfo-mode)
+       (with-current-buffer export-buffer
+         (goto-char (point-min))
+         (re-search-forward "^@node Top, Next, Previous, Up$"))))))
+
 (provide 'test-ox-texinfo)
 ;;; test-ox-texinfo.el end here
-- 
2.39.3 (Apple Git-146)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-ox-texinfo-Add-support-for-links-in-titles.patch --]
[-- Type: text/x-patch, Size: 4784 bytes --]

From 25170ef19a54909fd49c26de50d9396dc63ed3c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rudolf=20Adamkovi=C4=8D?= <rudolf@adamkovic.org>
Date: Thu, 22 Aug 2024 18:11:35 +0200
Subject: [PATCH 2/2] ox-texinfo: Add support for links in titles

* etc/ORG-NEWS (Texinfo export backend now allows links to be used in
headings): Inform end users about the new feature.
* lisp/ox-texinfo.el: (org-texinfo--format-entries,
org-texinfo--get-node, org-texinfo--sanitize-title-reference,
org-texinfo--sanitize-title): A 2-step change: (1) Rename
`--sanitize-title' to `--sanitize-title-reference' and (2) create a
new `--sanitize-title' sanitation function.  The new function is less
strict in that does not remove links, which should be allowed in
sectioning commands, such as `@unnumbered'.  The old function remains
more strict, which is useful for generating `@node' names, for
example.
* testing/lisp/test-ox-texinfo.el:
(test-ox-texinfo/headings-with-links): Test the new functionality to
avoid regressions in the future.
---
 etc/ORG-NEWS                    |  4 ++++
 lisp/ox-texinfo.el              | 17 +++++++++++++++--
 testing/lisp/test-ox-texinfo.el | 28 ++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 25dd3ae49..b6d9c54ef 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -230,6 +230,10 @@ This way, attachments will remain accessible when opening symlinked Org file.
 When no attach dir exists, Org mode will still prefer creating it in
 the "default" directory - where the symlink is located.
 
+*** Texinfo export can have links in headings
+
+The Texinfo export backend no longer removes links from headings.
+
 * Version 9.7
 
 ** Important announcements and breaking changes
diff --git a/lisp/ox-texinfo.el b/lisp/ox-texinfo.el
index a396d93d3..e39d7da97 100644
--- a/lisp/ox-texinfo.el
+++ b/lisp/ox-texinfo.el
@@ -524,7 +524,7 @@ node or anchor name is unique."
 		(org-texinfo--sanitize-node
 		 (pcase (org-element-type datum)
 		   (`headline
-		    (org-texinfo--sanitize-title
+		    (org-texinfo--sanitize-title-reference
 		     (org-export-get-alt-title datum info) info))
 		   (`radio-target
 		    (org-export-data (org-element-contents datum) info))
@@ -569,6 +569,19 @@ periods, commas and colons."
 (defun org-texinfo--sanitize-title (title info)
   "Make TITLE suitable as a section name.
 TITLE is a string or a secondary string.  INFO is the current
+export state, as a plist."
+  (org-export-data-with-backend
+   title
+   (org-export-create-backend
+    :parent 'texinfo
+    :transcoders `((footnote-reference . ,#'ignore)
+                   (radio-target . ,(lambda (_r c _) c))
+                   (target . ,#'ignore)))
+   info))
+
+(defun org-texinfo--sanitize-title-reference (title info)
+  "Make TITLE suitable as a section reference.
+TITLE is a string or a secondary string.  INFO is the current
 export state, as a plist."
   (org-export-data-with-backend
    title (org-export-toc-entry-backend 'texinfo) info))
@@ -1479,7 +1492,7 @@ a plist containing contextual information."
 	      ;; name.  Remove them.
 	      (replace-regexp-in-string
 	       "[ \t]*:+" ""
-	       (org-texinfo--sanitize-title
+	       (org-texinfo--sanitize-title-reference
 		(org-export-get-alt-title h info) info)))
 	     (node (org-texinfo--get-node h info))
 	     (entry (concat "* " title ":"
diff --git a/testing/lisp/test-ox-texinfo.el b/testing/lisp/test-ox-texinfo.el
index fe931baa4..f70abba50 100644
--- a/testing/lisp/test-ox-texinfo.el
+++ b/testing/lisp/test-ox-texinfo.el
@@ -478,5 +478,33 @@ body
          (goto-char (point-min))
          (re-search-forward "^@node Top, Next, Previous, Up$"))))))
 
+\f
+;;; Headings with links
+
+(ert-deftest test-ox-texinfo/headings-with-links ()
+  "Test node and chapter names."
+  (should
+   (org-test-with-temp-text
+       (string-join
+        (list "* Heading 1"
+              "  ...."
+              "* Heading 2 ([[* Heading 1][Heading 1]])"
+              "  ....")
+        "\n")
+     (let ((export-buffer "*Test Texinfo Export*")
+           (org-export-show-temporary-export-buffer nil))
+       (org-export-to-buffer 'texinfo export-buffer
+         nil nil nil nil nil
+         #'texinfo-mode)
+       (with-current-buffer export-buffer
+         (goto-char (point-min))
+         (search-forward "* Heading 1::")
+         (search-forward "* Heading 2 (Heading 1)::")
+         (search-forward "@node Heading 1")
+         (search-forward "@chapter Heading 1")
+         (search-forward "@node Heading 2 (Heading 1)")
+         (search-forward "@chapter Heading 2 (@ref{Heading 1})")
+         (buffer-string))))))
+
 (provide 'test-ox-texinfo)
 ;;; test-ox-texinfo.el end here
-- 
2.39.3 (Apple Git-146)


[-- Attachment #4: Type: text/plain, Size: 214 bytes --]

-- 
"All you have to do is write one true sentence.  Write the truest
sentence that you know."  --- Ernest Miller Hemingway (1899-1961)

Rudolf Adamkovič <rudolf@adamkovic.org> [he/him]
http://adamkovic.org

  reply	other threads:[~2024-08-23 12:46 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-22 18:20 Texinfo: Custom navigation and links in headings Rudolf Adamkovič
2024-08-23  7:08 ` Rudolf Adamkovič
2024-08-23 12:45   ` Rudolf Adamkovič [this message]
2024-08-24  6:46     ` [PATCH] Re: Texinfo: Custom navigation and links in headings (was: Texinfo: Custom navigation and links in headings) Rudolf Adamkovič
2024-08-24  9:19       ` [PATCH] Re: Texinfo: Custom navigation and links in headings Rudolf Adamkovič
2024-08-24 19:54         ` [PATCH v3] Improvements to Texinfo exporter (was: [PATCH] Re: Texinfo: Custom navigation and links in headings) Rudolf Adamkovič
2024-08-30 13:19           ` Rudolf Adamkovič
2024-08-31 13:36             ` Ihor Radchenko
2024-08-31 20:48             ` Rudolf Adamkovič

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=m2v7zrh0go.fsf@adamkovic.org \
    --to=rudolf@adamkovic.org \
    --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).