From 446bfc8c8afb5b2e09d0e0acf7b136b9f0780f5a Mon Sep 17 00:00:00 2001 Message-ID: <446bfc8c8afb5b2e09d0e0acf7b136b9f0780f5a.1713016519.git.yantar92@posteo.net> From: Ihor Radchenko Date: Sat, 13 Apr 2024 16:53:48 +0300 Subject: [PATCH] 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 --- etc/ORG-NEWS | 8 +++++ lisp/ox-html.el | 77 +++++++++++++++++++++++++++++-------------------- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index e61bd6988..1b7040815 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -13,6 +13,14 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org. * Version 9.7 (not released yet) ** 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 Previously, Org mode interpreted =(_text_)= as subscript. diff --git a/lisp/ox-html.el b/lisp/ox-html.el index 0471a573b..1262da1aa 100644 --- a/lisp/ox-html.el +++ b/lisp/ox-html.el @@ -1873,36 +1873,42 @@ (defun org-html-footnote-section (info) (pcase (org-export-collect-footnote-definitions info) (`nil nil) (definitions + (format + (plist-get info :html-footnotes-section) + (org-html--translate "Footnotes" info) (format - (plist-get info :html-footnotes-section) - (org-html--translate "Footnotes" info) - (format - "\n%s\n" - (mapconcat - (lambda (definition) - (pcase definition - (`(,n ,_ ,def) - ;; `org-export-collect-footnote-definitions' can return - ;; two kinds of footnote definitions: inline and blocks. - ;; Since this should not make any difference in the HTML - ;; output, we wrap the inline definitions within - ;; a "footpara" class paragraph. - (let ((inline? (not (org-element-map def org-element-all-elements - #'identity nil t))) - (anchor (org-html--anchor - (format "fn.%d" n) - n - (format " class=\"footnum\" href=\"#fnr.%d\" role=\"doc-backlink\"" n) - info)) - (contents (org-trim (org-export-data def info)))) - (format "
%s %s
\n" - (format (plist-get info :html-footnote-format) anchor) - (format "
%s
" - (if (not inline?) contents - (format "

%s

" - contents)))))))) - definitions - "\n")))))) + "\n%s\n" + (mapconcat + (lambda (definition) + (pcase definition + (`(,n ,label ,def) + ;; 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. + (when (equal label (number-to-string (string-to-number label))) + (setq label nil)) + ;; `org-export-collect-footnote-definitions' can return + ;; two kinds of footnote definitions: inline and blocks. + ;; Since this should not make any difference in the HTML + ;; output, we wrap the inline definitions within + ;; a "footpara" class paragraph. + (let ((inline? (not (org-element-map def org-element-all-elements + #'identity nil t))) + (anchor (org-html--anchor + (format "fn.%d" n) + n + (format " class=\"footnum\" href=\"#fnr.%s\" role=\"doc-backlink\"" (or label n)) + info)) + (contents (org-trim (org-export-data def info)))) + (format "
%s %s
\n" + (format (plist-get info :html-footnote-format) anchor) + (format "
%s
" + (if (not inline?) contents + (format "

%s

" + contents)))))))) + definitions + "\n")))))) ;;; Template @@ -2736,8 +2742,15 @@ (defun org-html-footnote-reference (footnote-reference _contents info) (when (org-element-type-p prev 'footnote-reference) (plist-get info :html-footnote-separator))) (let* ((n (org-export-get-footnote-number footnote-reference info)) - (id (format "fnr.%d%s" - n + (label (org-element-property :label footnote-reference)) + ;; 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 (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 footnote-reference info) "" @@ -2745,7 +2758,7 @@ (defun org-html-footnote-reference (footnote-reference _contents info) (format (plist-get info :html-footnote-format) (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 -- 2.44.0