I kept it simple.
Related-to: https://list.orgmode.org/orgmode/[email protected]/
From a40a57ea3bcc19a8ab53d6b505b24f2d0d1be4f0 Mon Sep 17 00:00:00 2001
From: ApollonDeParnasse <[email protected]>
Date: Fri, 5 Jun 2026 21:03:35 -0500
Subject: [PATCH] lisp/ox.el: Added option to export file links verbatim
* lisp/ox.el (org-export-file-links-verbatim): New custom option.
When non-nil, `file:' will not be appended to file links that
start with `\' before they are exported.
(org-export-options-alist): Recognize `org-export-options-alist'.
(org-export-file-uri): Will not prepend `file:' to file links
if they start `\' and `org-export-file-links-verbatim'
is non-nil.
* testing/lisp/test-ox.el (test-org-export/file-uri/with-verbatim-file-links):
New test for `org-export-file-uri'.
---
etc/ORG-NEWS | 11 +++++++++++
lisp/ox.el | 9 +++++++++
testing/lisp/test-ox.el | 21 +++++++++++++++++++++
3 files changed, 41 insertions(+)
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 5a72b69ea..3f44032c8 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -208,6 +208,17 @@ environment for descriptive lists when exporting to LaTeX.
Use it when the default ~description~ environment does not fit your
needs. The recommended alternative value is ~itemize~.
+*** New custom variable ~org-export-file-links-verbatim~
+
+~org-export-file-links-verbatim~ controls whether Org
+mode exports file links that start with "/" verbatim.
+Set it to t to export said links without first appending
+~file:~ to them.
+
+This variable has no effect on links that are already prefixed with
+=file:= or links that start with a =~=.
+
+
** New functions and changes in function arguments
# This also includes changes in function behavior from Elisp perspective.
diff --git a/lisp/ox.el b/lisp/ox.el
index e0782c1e6..f7a5d6504 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -123,6 +123,7 @@
(:with-author nil "author" org-export-with-author)
(:expand-links nil "expand-links" org-export-expand-links)
(:with-broken-links nil "broken-links" org-export-with-broken-links)
+ (:verbatim-file-links nil "verbatim-file-links" org-export-file-links-verbatim)
(:with-clocks nil "c" org-export-with-clocks)
(:with-creator nil "creator" org-export-with-creator)
(:with-date nil "date" org-export-with-date)
@@ -880,6 +881,13 @@ This option can also be set with the OPTIONS keyword, e.g.,
:package-version '(Org . "9.7")
:type 'boolean)
+(defcustom org-export-file-links-verbatim nil
+ "Non-nil means export file links that start with `/' verbatim.
+`file:' will not be prepended to the path of these links."
+ :group 'org-export-general
+ :package-version '(Org . "9.8")
+ :type 'boolean)
+
(defcustom org-export-replace-macros t
"When non-nil, replace macros before export.
This variable does not affect {{{results}}} macros when processing
@@ -4689,6 +4697,7 @@ Return value can be an object or an element:
(cond ((string-prefix-p "//" filename) (concat "file:" filename))
((not (file-name-absolute-p filename)) filename)
((file-remote-p filename) (concat "file:/" filename))
+ ((and org-export-file-links-verbatim (not (string-prefix-p "~" filename))) filename)
(t
(let ((fullname (expand-file-name filename)))
(concat (if (string-prefix-p "/" fullname) "file://" "file:///")
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index 79365ad29..3660073d5 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -3969,6 +3969,27 @@ Another text. (ref:text)
(should (equal (org-export-file-uri "~/file.org")
(concat (if (memq system-type '(windows-nt cygwin)) "file:///" "file://") (expand-file-name "~/file.org")))))
+(ert-deftest test-org-export/file-uri/with-verbatim-file-links ()
+ "Test `org-export-file-uri' with `org-export-file-links-verbatim' enabled."
+ (let ((org-export-file-links-verbatim t))
+ (should (equal
+ "/en/install-emacs-on-android"
+ (org-export-file-uri "/en/install-emacs-on-android")))
+ (should (equal
+ "/dominik/images/jupiter.jpg"
+ (org-export-file-uri "/dominik/images/jupiter.jpg")))
+ ;;Doesn't effect Local files start with "file://"
+ (should (equal "file:/local.org"
+ (org-export-file-uri "file:/local.org")))
+
+ ;;Doesn't effect remote files with "file://"
+ (should (equal "file://ssh:[email protected]:papers/last.pdf"
+ (org-export-file-uri "/ssh:[email protected]:papers/last.pdf")))
+
+ ;; Doesn't effect filenames that start with "~".
+ (should (equal (org-export-file-uri "~/file.org")
+ (concat (if (memq system-type '(windows-nt cygwin)) "file:///" "file://") (expand-file-name "~/file.org"))))))
+
(ert-deftest test-org-export/get-reference ()
"Test `org-export-get-reference' specifications."
(should
--
2.54.0