> > Exporting an ID link to HTML produces a link of the form <a
> > href="file.html#id>. This makes sense if linking to a section ID. However,
> > in the case of a file ID, the #id part is unnecessary, and in fact a file
> > ID does not occur anywhere in the exported file. I wonder if it would be
> > reasonable to simply remove the #id part in links to files.
> Yes, that would make sense.
> Patches welcome!
I have attached a patch that addresses the issue (in my testing). Basically,
whenever an ID link is encountered during export, we open the corresponding
file and check whether that matches the file's ID. If it does, we transcode to
an HTML link with no anchor.
The big caveat here is that opening a file each time an ID link is encountered
could cause performance problems.
In theory, :id-alist in the communication channel could carry information about
whether a given ID corresponds to a file or a header. However, that would be a
big change for a niche problem.
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index e9ac48d20..e7681fd4b 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -3446,12 +3446,19 @@ INFO is a plist holding contextual information. See
(pcase (org-element-type destination)
;; ID link points to an external file.
(`plain-text
- (let ((fragment (concat org-html--id-attr-prefix raw-path))
- ;; Treat links to ".org" files as ".html", if needed.
- (path (funcall link-org-files-as-html-maybe
+ ;; Treat links to ".org" files as ".html", if needed.
+ (let ((path (funcall link-org-files-as-html-maybe
destination info)))
- (format "<a href=\"%s#%s\"%s>%s</a>"
- path fragment attributes (or desc destination))))
+ ;; Check whether the ID references a file rather than a headline.
+ (if (org-with-file-buffer destination
+ (save-excursion
+ (goto-char (point-min))
+ (and (org-before-first-heading-p)
+ (string= (org-entry-get (point) "ID") (org-element-property :path link)))))
+ (format "<a href=\"%s\"%s>%s</a>" path attributes (or desc destination))
+ (let ((fragment (concat org-html--id-attr-prefix raw-path))
+ (format "<a href=\"%s#%s\"%s>%s</a">
+ path fragment attributes (or desc destination)))))))
;; Fuzzy link points nowhere.
(`nil
(format "<i>%s</i>"