diff --git a/lisp/org-src.el b/lisp/org-src.el index 9c462b7e7..12163156f 100644 --- a/lisp/org-src.el +++ b/lisp/org-src.el @@ -283,6 +283,10 @@ However, if `indent-tabs-mode' is nil in that buffer, its value is 0.") (put 'org-src--tab-width 'permanent-local t) +(defvar-local org-src-source-file-name nil + "File name associated to Org source buffer, or nil.") +(put 'org-src-source-file-name 'permanent-local t) + (defun org-src--construct-edit-buffer-name (org-buffer-name lang) "Construct the buffer name for a source editing buffer." (concat "*Org Src " org-buffer-name "[ " lang " ]*")) @@ -300,12 +304,6 @@ Return nil if there is no such buffer." (eq (marker-buffer end) (marker-buffer org-src--end-marker)) (throw 'exit b)))))) -(defun org-src--source-buffer () - "Return source buffer edited by current buffer." - (unless (org-src-edit-buffer-p) (error "Not in a source buffer")) - (or (marker-buffer org-src--beg-marker) - (error "No source buffer available for current editing session"))) - (defun org-src--get-lang-mode (lang) "Return major mode that should be used for LANG. LANG is a string, and the returned major mode is a symbol." @@ -493,6 +491,7 @@ Leave point in edit buffer." (with-current-buffer old-edit-buffer (org-src--remove-overlay)) (kill-buffer old-edit-buffer)) (let* ((org-mode-p (derived-mode-p 'org-mode)) + (source-file-name (buffer-file-name (buffer-base-buffer))) (source-tab-width (if indent-tabs-mode tab-width 0)) (type (org-element-type datum)) (ind (org-with-wide-buffer @@ -544,6 +543,7 @@ Leave point in edit buffer." (setq org-src--preserve-indentation preserve-ind) (setq org-src--overlay overlay) (setq org-src--allow-write-back write-back) + (setq org-src-source-file-name source-file-name) ;; Start minor mode. (org-src-mode) ;; Move mark and point in edit buffer to the corresponding @@ -774,6 +774,19 @@ If BUFFER is non-nil, test it instead." (local-variable-p 'org-src--beg-marker buffer) (local-variable-p 'org-src--end-marker buffer)))) +(defun org-src-source-buffer () + "Return source buffer edited in current buffer. +Raise an error when current buffer is not a source editing buffer." + (unless (org-src-edit-buffer-p) (error "Not in a source buffer")) + (or (marker-buffer org-src--beg-marker) + (error "No source buffer available for current editing session"))) + +(defun org-src-source-type () + "Return type of element edited in current buffer. +Raise an error when current buffer is not a source editing buffer." + (unless (org-src-edit-buffer-p) (error "Not in a source buffer")) + org-src--source-type) + (defun org-src-switch-to-buffer (buffer context) (pcase org-src-window-setup (`current-window (pop-to-buffer-same-window buffer)) @@ -1103,7 +1116,7 @@ Throw an error if there is no such buffer." (beg org-src--beg-marker) (end org-src--end-marker) (overlay org-src--overlay)) - (with-current-buffer (org-src--source-buffer) + (with-current-buffer (org-src-source-buffer) (undo-boundary) (goto-char beg) ;; Temporarily disable read-only features of OVERLAY in order to diff --git a/lisp/org.el b/lisp/org.el index 71921cfe8..33c846765 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -9244,27 +9244,40 @@ non-nil." ;; Store a link from a remote editing buffer. ((org-src-edit-buffer-p) - (let ((coderef-format (org-src-coderef-format))) + (let ((coderef-format (org-src-coderef-format)) + (format-link + (lambda (label) + (if org-src-source-file-name + (format "file:%s::(%s)" org-src-source-file-name label) + (format "(%s)" label))))) (cond - ;; A code reference exists. Use it. + ;; Code references do not exist in this type of buffer. + ;; Pretend we're linking from the source buffer directly. + ((not (memq (org-src-source-type) '(example-block src-block))) + (with-current-buffer (org-src-source-buffer) + (org-store-link arg interactive?)) + (setq link nil)) + ;; A code reference exists. Use it. ((save-excursion (beginning-of-line) (re-search-forward (org-src-coderef-regexp coderef-format) (line-end-position) t)) - (setq link (format "(%s)" (match-string-no-properties 3)))) + (setq link (funcall format-link (match-string-no-properties 3)))) ;; No code reference. Create a new one then store the link ;; to it, but only in the function is called interactively. (interactive? (end-of-line) (let* ((label (read-string "Code line label: ")) (reference (format coderef-format label)) - (gc (- 79 (length link)))) + (gc (- 79 (length reference)))) (if (< (current-column) gc) (org-move-to-column gc t) (insert " ")) (insert reference) - (setq link (format "(%s)" label)))) + (setq link (funcall format-link label)))) + ;; No code reference, and non-interactive call. Don't know + ;; what to do. Give up. (t (setq link nil))))) ;; We are in the agenda, link to referenced location @@ -10469,18 +10482,12 @@ of matched result, which is either `dedicated' or `fuzzy'." (let ((element (org-element-at-point))) (when (and (memq (org-element-type element) '(example-block src-block)) - ;; Build proper regexp according to current - ;; block's label format. - (let ((label-fmt - (regexp-quote - (or (org-element-property :label-fmt element) - org-coderef-label-format)))) - (save-excursion - (beginning-of-line) - (looking-at (format ".*?\\(%s\\)[ \t]*$" - (format label-fmt coderef)))))) + (org-match-line + (concat ".*?" (org-src-coderef-regexp + (org-src-coderef-format element) + coderef)))) (setq type 'dedicated) - (goto-char (match-beginning 1)) + (goto-char (match-beginning 2)) (throw :coderef-match nil)))) (goto-char origin) (error "No match for coderef: %s" coderef)))) diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el index 70ef9de2e..fd1cb1d03 100644 --- a/lisp/ox-odt.el +++ b/lisp/ox-odt.el @@ -1360,6 +1360,9 @@ original parsed data. INFO is a plist holding export options." (let* ((styles-file (plist-get info :odt-styles-file)) (styles-file (and (org-string-nw-p styles-file) (org-trim styles-file))) + (styles-file (if (string-match-p "\\`(.*)\\'" styles-file) + (ignore-errors (read styles-file)) + styles-file)) ;; Non-availability of styles.xml is not a critical ;; error. For now, throw an error. (styles-file (or styles-file