ox-html: Use non-number footnote names as link anchors

* lisp/ox-html.el (org-html-footnote-section):
* lisp/ox-html.el (org-html-footnote-reference): When footnote has a
non-number name, build link anchors using this name.
* etc/ORG-NEWS (=ox-html=: When exporting footnotes with custom
non-number names, the names are used as link anchors): Announce the
change.

Link: https://orgmode.org/list/875xwngiwx.fsf@protesilaos.com

Co-authored-by: Protesilaos Stavrou <info@protesilaos.com>
This commit is contained in:
Ihor Radchenko 2024-04-13 16:53:48 +03:00
parent ba747598c6
commit 065af4b42a
No known key found for this signature in database
GPG Key ID: 6470762A7DA11D8B
2 changed files with 56 additions and 32 deletions

View File

@ -13,6 +13,14 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
* Version 9.7 (not released yet) * Version 9.7 (not released yet)
** Important announcements and breaking changes ** Important announcements and breaking changes
*** =ox-html=: When exporting footnotes with custom non-number names, the names are used as link anchors
Previously, link anchors for footnote references and footnote
definitions were based on the footnote number: =fn.1=, =fnr.15=, etc.
Now, when the footnote has a non-number name, it is used as an anchor:
=fn.name=, =fnr.name=.
*** Underline syntax now takes priority over subscript when both are applicable *** Underline syntax now takes priority over subscript when both are applicable
Previously, Org mode interpreted =(_text_)= as subscript. Previously, Org mode interpreted =(_text_)= as subscript.

View File

@ -1873,36 +1873,43 @@ INFO is a plist used as a communication channel."
(pcase (org-export-collect-footnote-definitions info) (pcase (org-export-collect-footnote-definitions info)
(`nil nil) (`nil nil)
(definitions (definitions
(format
(plist-get info :html-footnotes-section)
(org-html--translate "Footnotes" info)
(format (format
(plist-get info :html-footnotes-section) "\n%s\n"
(org-html--translate "Footnotes" info) (mapconcat
(format (lambda (definition)
"\n%s\n" (pcase definition
(mapconcat (`(,n ,label ,def)
(lambda (definition) ;; Do not assign number labels as they appear in Org mode
(pcase definition ;; - the footnotes are re-numbered by
(`(,n ,_ ,def) ;; `org-export-get-footnote-number'. If the label is not
;; `org-export-collect-footnote-definitions' can return ;; a number, keep it.
;; two kinds of footnote definitions: inline and blocks. (when (and (stringp label)
;; Since this should not make any difference in the HTML (equal label (number-to-string (string-to-number label))))
;; output, we wrap the inline definitions within (setq label nil))
;; a "footpara" class paragraph. ;; `org-export-collect-footnote-definitions' can return
(let ((inline? (not (org-element-map def org-element-all-elements ;; two kinds of footnote definitions: inline and blocks.
#'identity nil t))) ;; Since this should not make any difference in the HTML
(anchor (org-html--anchor ;; output, we wrap the inline definitions within
(format "fn.%d" n) ;; a "footpara" class paragraph.
n (let ((inline? (not (org-element-map def org-element-all-elements
(format " class=\"footnum\" href=\"#fnr.%d\" role=\"doc-backlink\"" n) #'identity nil t)))
info)) (anchor (org-html--anchor
(contents (org-trim (org-export-data def info)))) (format "fn.%s" (or label n))
(format "<div class=\"footdef\">%s %s</div>\n" n
(format (plist-get info :html-footnote-format) anchor) (format " class=\"footnum\" href=\"#fnr.%s\" role=\"doc-backlink\"" (or label n))
(format "<div class=\"footpara\" role=\"doc-footnote\">%s</div>" info))
(if (not inline?) contents (contents (org-trim (org-export-data def info))))
(format "<p class=\"footpara\">%s</p>" (format "<div class=\"footdef\">%s %s</div>\n"
contents)))))))) (format (plist-get info :html-footnote-format) anchor)
definitions (format "<div class=\"footpara\" role=\"doc-footnote\">%s</div>"
"\n")))))) (if (not inline?) contents
(format "<p class=\"footpara\">%s</p>"
contents))))))))
definitions
"\n"))))))
;;; Template ;;; Template
@ -2741,8 +2748,17 @@ CONTENTS is nil. INFO is a plist holding contextual information."
(when (org-element-type-p prev 'footnote-reference) (when (org-element-type-p prev 'footnote-reference)
(plist-get info :html-footnote-separator))) (plist-get info :html-footnote-separator)))
(let* ((n (org-export-get-footnote-number footnote-reference info)) (let* ((n (org-export-get-footnote-number footnote-reference info))
(id (format "fnr.%d%s" (label (org-element-property :label footnote-reference))
n ;; Do not assign number labels as they appear in Org mode -
;; the footnotes are re-numbered by
;; `org-export-get-footnote-number'. If the label is not a
;; number, keep it.
(label (if (and (stringp label)
(equal label (number-to-string (string-to-number label))))
nil
label))
(id (format "fnr.%s%s"
(or label n)
(if (org-export-footnote-first-reference-p (if (org-export-footnote-first-reference-p
footnote-reference info) footnote-reference info)
"" ""
@ -2750,7 +2766,7 @@ CONTENTS is nil. INFO is a plist holding contextual information."
(format (format
(plist-get info :html-footnote-format) (plist-get info :html-footnote-format)
(org-html--anchor (org-html--anchor
id n (format " class=\"footref\" href=\"#fn.%d\" role=\"doc-backlink\"" n) info))))) id n (format " class=\"footref\" href=\"#fn.%s\" role=\"doc-backlink\"" (or label n)) info)))))
;;;; Headline ;;;; Headline