emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* texinfo export has no targets for src blocks
@ 2024-12-14 14:22 Fraga, Eric
  2024-12-23 15:10 ` Ihor Radchenko
  0 siblings, 1 reply; 4+ messages in thread
From: Fraga, Eric @ 2024-12-14 14:22 UTC (permalink / raw)
  To: Emacs Org mode mailing list

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

Hello all,

Just a heads up as I spent some time debugging a problem with export to
texinfo.  If you have a heading, say

** The model <<model>>

but also happen to have a code block

#+name: model
#+begin_src ...

exporting to texinfo, asking to refer to [[model]], creates a reference
to an non-existing target ("model") because (a) org appears to assume
that you wish to reference the src block, not the headline, and (b) the
src block (/@example/ in texinfo) is not labelled in the .texi output.
See attached minimal example.

I was actually trying to reference the headline so changed <<model>> to
<<modelsection>> and [[model]] to [[modelsection]] and everything is
fine.

Note: org-lint does not catch multiple entities/elements assigned the
same name.  I have no idea whether it should or not.  Debatable, I
guess.

Back to your normal programming.

Thank you,
eric

-- 
: Eric S Fraga, with org 9.7.17-3ae179 in Emacs 31.0.50

[-- Attachment #2: infotest.org --]
[-- Type: application/vnd.lotus-organizer, Size: 219 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: texinfo export has no targets for src blocks
  2024-12-14 14:22 texinfo export has no targets for src blocks Fraga, Eric
@ 2024-12-23 15:10 ` Ihor Radchenko
  2024-12-23 15:25   ` Fraga, Eric
  0 siblings, 1 reply; 4+ messages in thread
From: Ihor Radchenko @ 2024-12-23 15:10 UTC (permalink / raw)
  To: Fraga, Eric; +Cc: Emacs Org mode mailing list

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

"Fraga, Eric" <e.fraga@ucl.ac.uk> writes:

> but also happen to have a code block
>
> #+name: model
> #+begin_src ...
>
> exporting to texinfo, asking to refer to [[model]], creates a reference
> to an non-existing target ("model") because (a) org appears to assume
> that you wish to reference the src block, not the headline, and (b) the
> src block (/@example/ in texinfo) is not labelled in the .texi output.
> See attached minimal example.
> ...

Thanks for reporting!
I tried to add support for #+name'd elements in ox-texinfo.
See the attached patch.

I simply prepended an @anchor to all paragraph level Org markup
elements. However, I am not 100% sure if it is always safe to do.
May you please test the patch on your side to make sure that things are
not going to be broken? (they are not on Org manual, at least)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-texinfo-Support-references-to-name-d-elements.patch --]
[-- Type: text/x-patch, Size: 12835 bytes --]

From 3055cf517ba665f00820a179299df4cb43333c9b Mon Sep 17 00:00:00 2001
Message-ID: <3055cf517ba665f00820a179299df4cb43333c9b.1734966481.git.yantar92@posteo.net>
From: Ihor Radchenko <yantar92@posteo.net>
Date: Mon, 23 Dec 2024 16:06:07 +0100
Subject: [PATCH] ox-texinfo: Support references to #+name'd elements

* lisp/ox-texinfo.el (org-texinfo--prepend-anchor-maybe): New helper
function prepending an archor to named text.
(org-texinfo-center-block):
(org-texinfo-drawer):
(org-texinfo-dynamic-block):
(org-texinfo-example-block):
(org-texinfo-fixed-width):
(org-texinfo-latex-environment):
(org-texinfo-paragraph):
(org-texinfo-plain-list):
(org-texinfo-quote-block):
(org-texinfo-special-block):
(org-texinfo-src-block):
(org-texinfo-table):
(org-texinfo-verse-block): Use the new helper.
* testing/lisp/test-ox-texinfo.el (test-ox-texinfo/anchors): New test.

Reported-by: Fraga, Eric <e.fraga@ucl.ac.uk>
Link: https://orgmode.org/list/87h676qr8n.fsf@ucl.ac.uk
---
 lisp/ox-texinfo.el              | 124 ++++++++++++++++++++------------
 testing/lisp/test-ox-texinfo.el |  50 +++++++++++++
 2 files changed, 128 insertions(+), 46 deletions(-)

diff --git a/lisp/ox-texinfo.el b/lisp/ox-texinfo.el
index cf7a96f78d..9e96d6c94f 100644
--- a/lisp/ox-texinfo.el
+++ b/lisp/ox-texinfo.el
@@ -553,6 +553,14 @@ (defun org-texinfo--get-node (datum info)
 	  (plist-put info :texinfo-node-cache (cons (cons datum name) cache))
 	  name))))
 
+(defun org-texinfo--prepend-anchor-maybe (contents node)
+  "Maybe prepend NODE anchor before CONTENTS.
+When NODE has :name property, prepend anchor named as :name value to
+CONTENTS.  Otherwise, return CONTENTS."
+  (if-let* ((label (org-element-property :name node)))
+      (concat "@anchor{" label "}\n" contents)
+    contents))
+
 (defun org-texinfo--sanitize-node (title)
   "Bend string TITLE to node line requirements.
 Trim string and collapse multiple whitespace characters as they
@@ -930,11 +938,13 @@ (defun org-texinfo-bold (_bold contents info)
 
 ;;;; Center Block
 
-(defun org-texinfo-center-block (_center-block contents _info)
+(defun org-texinfo-center-block (center-block contents _info)
   "Transcode a CENTER-BLOCK element from Org to Texinfo.
 CONTENTS holds the contents of the block.  INFO is a plist used
 as a communication channel."
-  (replace-regexp-in-string "\\(^\\).*?\\S-" "@center " contents nil nil 1))
+  (org-texinfo--prepend-anchor-maybe
+   (replace-regexp-in-string "\\(^\\).*?\\S-" "@center " contents nil nil 1)
+   center-block))
 
 ;;;; Clock
 
@@ -968,15 +978,15 @@ (defun org-texinfo-drawer (drawer contents info)
   (let* ((name (org-element-property :drawer-name drawer))
 	 (output (funcall (plist-get info :texinfo-format-drawer-function)
 			  name contents)))
-    output))
+    (org-texinfo--prepend-anchor-maybe output drawer)))
 
 ;;;; Dynamic Block
 
-(defun org-texinfo-dynamic-block (_dynamic-block contents _info)
+(defun org-texinfo-dynamic-block (dynamic-block contents _info)
   "Transcode a DYNAMIC-BLOCK element from Org to Texinfo.
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
-  contents)
+  (org-texinfo--prepend-anchor-maybe contents dynamic-block))
 
 ;;;; Entity
 
@@ -1028,9 +1038,11 @@ (defun org-texinfo-example-block (example-block _contents info)
   "Transcode an EXAMPLE-BLOCK element from Org to Texinfo.
 CONTENTS is nil.  INFO is a plist holding contextual
 information."
-  (format "@example\n%s@end example"
-	  (org-texinfo--sanitize-content
-	   (org-export-format-code-default example-block info))))
+  (org-texinfo--prepend-anchor-maybe
+   (format "@example\n%s@end example"
+	   (org-texinfo--sanitize-content
+	    (org-export-format-code-default example-block info)))
+   example-block))
 
 ;;; Export Block
 
@@ -1053,10 +1065,12 @@ ;;;; Fixed Width
 (defun org-texinfo-fixed-width (fixed-width _contents _info)
   "Transcode a FIXED-WIDTH element from Org to Texinfo.
 CONTENTS is nil.  INFO is a plist holding contextual information."
-  (format "@example\n%s\n@end example"
-	  (org-remove-indentation
-	   (org-texinfo--sanitize-content
-	    (org-element-property :value fixed-width)))))
+  (org-texinfo--prepend-anchor-maybe
+   (format "@example\n%s\n@end example"
+	   (org-remove-indentation
+	    (org-texinfo--sanitize-content
+	     (org-element-property :value fixed-width))))
+   fixed-width))
 
 ;;;; Footnote Reference
 
@@ -1274,11 +1288,13 @@ (defun org-texinfo-latex-environment (environment _contents info)
     (when (or (eq with-latex t)
               (and (eq with-latex 'detect)
                    (org-texinfo-supports-math-p)))
-      (let ((value (org-element-property :value environment)))
-        (string-join (list "@displaymath"
-                           (string-trim (org-remove-indentation value))
-                           "@end displaymath")
-                     "\n")))))
+      (org-texinfo--prepend-anchor-maybe
+       (let ((value (org-element-property :value environment)))
+         (string-join (list "@displaymath"
+                            (string-trim (org-remove-indentation value))
+                            "@end displaymath")
+                      "\n"))
+       environment))))
 
 ;;;; LaTeX Fragment
 
@@ -1534,7 +1550,7 @@ (defun org-texinfo-node-property (node-property _contents _info)
 
 ;;;; Paragraph
 
-(defun org-texinfo-paragraph (_paragraph contents _info)
+(defun org-texinfo-paragraph (paragraph contents _info)
   "Transcode a PARAGRAPH element from Org to Texinfo.
 CONTENTS is the contents of the paragraph, as a string.  INFO is
 the plist used as a communication channel."
@@ -1543,7 +1559,9 @@ (defun org-texinfo-paragraph (_paragraph contents _info)
   ;; Multiple newlines may appear in CONTENTS, for example, when
   ;; certain objects are stripped from export, leaving single newlines
   ;; before and after.
-  (org-remove-blank-lines contents))
+  (org-texinfo--prepend-anchor-maybe
+   (org-remove-blank-lines contents)
+   paragraph))
 
 ;;;; Plain List
 
@@ -1571,12 +1589,14 @@ (defun org-texinfo-plain-list (plain-list contents info)
 		     ((eq type 'unordered) "itemize")
 		     ((member table-type '("ftable" "vtable")) table-type)
 		     (t "table"))))
-    (format "@%s\n%s@end %s"
-	    (cond ((eq type 'descriptive) (concat list-type " " indic))
-		  (enum (format "%s %s" list-type enum))
-		  (t list-type))
-	    contents
-	    list-type)))
+    (org-texinfo--prepend-anchor-maybe
+     (format "@%s\n%s@end %s"
+	     (cond ((eq type 'descriptive) (concat list-type " " indic))
+		   (enum (format "%s %s" list-type enum))
+		   (t list-type))
+	     contents
+	     list-type)
+     plain-list)))
 
 ;;;; Plain Text
 
@@ -1662,10 +1682,12 @@ (defun org-texinfo-quote-block (quote-block contents _info)
 holding contextual information."
   (let ((tag (org-export-read-attribute :attr_texinfo quote-block :tag))
 	(author (org-export-read-attribute :attr_texinfo quote-block :author)))
-    (format "@quotation%s\n%s%s\n@end quotation"
-	    (if tag (concat " " tag) "")
-	    contents
-	    (if author (concat "\n@author " author) ""))))
+    (org-texinfo--prepend-anchor-maybe
+     (format "@quotation%s\n%s%s\n@end quotation"
+	     (if tag (concat " " tag) "")
+	     contents
+	     (if author (concat "\n@author " author) ""))
+     quote-block)))
 
 ;;;; Radio Target
 
@@ -1702,11 +1724,13 @@ (defun org-texinfo-special-block (special-block contents _info)
               (org-element-property :ox-texinfo--options special-block)
               (org-export-read-attribute :attr_texinfo special-block :options)))
 	(type (org-element-property :type special-block)))
-    (format "@%s%s\n%s@end %s"
-	    type
-	    (if opt (concat " " opt) "")
-	    (or contents "")
-	    type)))
+    (org-texinfo--prepend-anchor-maybe
+     (format "@%s%s\n%s@end %s"
+	     type
+	     (if opt (concat " " opt) "")
+	     (or contents "")
+	     type)
+     special-block)))
 
 ;;;; Src Block
 
@@ -1724,13 +1748,15 @@ (defun org-texinfo-src-block (src-block _contents info)
 		 code))
 	 (caption (org-export-get-caption src-block))
 	 (shortcaption (org-export-get-caption src-block t)))
-    (if (not (or caption shortcaption)) value
+    (cond
+     ((or caption shortcaption)
       (org-texinfo--wrap-float value
 			       info
 			       (org-export-translate "Listing" :utf-8 info)
-			       (org-texinfo--get-node src-block info)
+                               (org-element-property :name src-block)
 			       caption
-			       shortcaption))))
+			       shortcaption))
+     (t (org-texinfo--prepend-anchor-maybe value src-block)))))
 
 ;;;; Statistics Cookie
 
@@ -1771,9 +1797,11 @@ (defun org-texinfo-table (table contents info)
 CONTENTS is the contents of the table.  INFO is a plist holding
 contextual information."
   (if (eq (org-element-property :type table) 'table.el)
-      (format "@verbatim\n%s@end verbatim"
-	      (org-element-normalize-string
-	       (org-element-property :value table)))
+      (org-texinfo--prepend-anchor-maybe
+       (format "@verbatim\n%s@end verbatim"
+	       (org-element-normalize-string
+	        (org-element-property :value table)))
+       table)
     (let* ((col-width (org-export-read-attribute :attr_texinfo table :columns))
 	   (columns
 	    (if col-width (format "@columnfractions %s" col-width)
@@ -1783,13 +1811,15 @@ (defun org-texinfo-table (table contents info)
 	   (table-str (format "@multitable %s\n%s@end multitable"
 			      columns
 			      contents)))
-      (if (not (or caption shortcaption)) table-str
-	(org-texinfo--wrap-float table-str
+      (cond
+       ((or caption shortcaption)
+        (org-texinfo--wrap-float table-str
 				 info
 				 (org-export-translate "Table" :utf-8 info)
-				 (org-texinfo--get-node table info)
+                                 (org-element-property :name table)
 				 caption
-				 shortcaption)))))
+				 shortcaption))
+       (t (org-texinfo--prepend-anchor-maybe table-str table))))))
 
 (defun org-texinfo-table-column-widths (table info)
   "Determine the largest table cell in each column to process alignment.
@@ -1891,11 +1921,13 @@ (defun org-texinfo-verbatim (verbatim _contents info)
 
 ;;;; Verse Block
 
-(defun org-texinfo-verse-block (_verse-block contents _info)
+(defun org-texinfo-verse-block (verse-block contents _info)
   "Transcode a VERSE-BLOCK element from Org to Texinfo.
 CONTENTS is verse block contents.  INFO is a plist holding
 contextual information."
-  (format "@display\n%s@end display" contents))
+  (org-texinfo--prepend-anchor-maybe
+   (format "@display\n%s@end display" contents)
+   verse-block))
 
 \f
 ;;; Public Functions
diff --git a/testing/lisp/test-ox-texinfo.el b/testing/lisp/test-ox-texinfo.el
index 681af7363e..6b6d16aea7 100644
--- a/testing/lisp/test-ox-texinfo.el
+++ b/testing/lisp/test-ox-texinfo.el
@@ -374,6 +374,56 @@ (ert-deftest test-ox-texinfo/references ()
           (re-search-forward "@ref{B, , B}")
           (re-search-forward "@ref{B, , C}")))))))
 
+(ert-deftest test-ox-texinfo/anchors ()
+  "Test anchors and references."
+  (should
+   (org-test-with-temp-text
+       (string-join
+        (list "* The document"
+              "** The model"
+              "This is some text describing the model."
+              "#+name: model"
+              "#+begin_src julia"
+              "  struct Model"
+              "  end"
+              "#+end_src"
+              "** Solution"
+              "Solving the model ([[model]]) leads to some interesting results."
+              )
+        "\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))
+         (and
+          (re-search-forward "@anchor{model}")
+          (re-search-forward "@ref{model}"))))))
+  (should
+   (org-test-with-temp-text
+       (string-join
+        (list "* The document"
+              "** The model"
+              "This is some text describing the model."
+              "#+name: model"
+              "| foo | bar |"
+              "** Solution"
+              "Solving the model ([[model]]) leads to some interesting results."
+              )
+        "\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))
+         (and
+          (re-search-forward "@anchor{model}")
+          (re-search-forward "@ref{model}")))))))
+
 \f
 ;;; Headings with links
 
-- 
2.47.1


[-- Attachment #3: Type: text/plain, Size: 223 bytes --]


-- 
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: texinfo export has no targets for src blocks
  2024-12-23 15:10 ` Ihor Radchenko
@ 2024-12-23 15:25   ` Fraga, Eric
  2024-12-23 16:20     ` Ihor Radchenko
  0 siblings, 1 reply; 4+ messages in thread
From: Fraga, Eric @ 2024-12-23 15:25 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: Emacs Org mode mailing list

Response below/inline for email Ihor Radchenko wrote:
> (original email sent 23 Dec 2024 at 15:10)
> 
> Thanks for reporting!
> I tried to add support for #+name'd elements in ox-texinfo.
> See the attached patch.

Seems to work fine, at least for both the minimal test and my long
document.  Thank you!

-- 
: Eric S Fraga, with org 9.7.17-3ae179 in Emacs 31.0.50

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: texinfo export has no targets for src blocks
  2024-12-23 15:25   ` Fraga, Eric
@ 2024-12-23 16:20     ` Ihor Radchenko
  0 siblings, 0 replies; 4+ messages in thread
From: Ihor Radchenko @ 2024-12-23 16:20 UTC (permalink / raw)
  To: Fraga, Eric; +Cc: Emacs Org mode mailing list

"Fraga, Eric" <e.fraga@ucl.ac.uk> writes:

> Response below/inline for email Ihor Radchenko wrote:
>> (original email sent 23 Dec 2024 at 15:10)
>> 
>> Thanks for reporting!
>> I tried to add support for #+name'd elements in ox-texinfo.
>> See the attached patch.
>
> Seems to work fine, at least for both the minimal test and my long
> document.  Thank you!

Thanks for checking!
Applied, onto main.
Fixed.
https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=fdee492e54

-- 
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-12-23 16:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-14 14:22 texinfo export has no targets for src blocks Fraga, Eric
2024-12-23 15:10 ` Ihor Radchenko
2024-12-23 15:25   ` Fraga, Eric
2024-12-23 16:20     ` Ihor Radchenko

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).