Browse Source

Consider edit buffers in `org-src-coderef-regexp'

* lisp/org-src.el (org-src-coderef-format): New function
(org-src-coderef-regexp): Change signature.

* lisp/ob-core.el (org-babel--normalize-body):
* lisp/ox.el (org-export-unravel-code): Use new functions.

* testing/lisp/test-org-src.el (test-org-src/coderef-format): New test.
Nicolas Goaziou 8 years ago
parent
commit
48af4166fd
4 changed files with 138 additions and 13 deletions
  1. 2 1
      lisp/ob-core.el
  2. 28 9
      lisp/org-src.el
  3. 4 3
      lisp/ox.el
  4. 104 0
      testing/lisp/test-org-src.el

+ 2 - 1
lisp/ob-core.el

@@ -555,7 +555,8 @@ character and coderef labels when appropriate."
 	;; paragraph filling.  Treat them as a white space.
 	(replace-regexp-in-string "\n[ \t]*" " " body)
       (let ((body (replace-regexp-in-string
-		   (org-src-coderef-regexp datum) "" body nil nil 1)))
+		   (org-src-coderef-regexp (org-src-coderef-format datum)) ""
+		   body nil nil 1)))
 	(if (or org-src-preserve-indentation
 		(org-element-property :preserve-indent datum))
 	    body

+ 28 - 9
lisp/org-src.el

@@ -715,19 +715,38 @@ If BUFFER is non-nil, test it instead."
 	      org-src-window-setup)
      (pop-to-buffer-same-window buffer))))
 
-(defun org-src-coderef-regexp (element)
-  "Return regexp matching coderef for ELEMENT.
+(defun org-src-coderef-format (&optional element)
+  "Return format string for block at point.
 
-ELEMENT has a `src-block' or `example-block' type.
+When optional argument ELEMENT is provided, use that block.
+Otherwise, assume point is either at a source block, at an
+example block.
+
+If point is in an edit buffer, retrieve format string associated
+to the remote source block."
+  (cond
+   ((and element (org-element-property :label-fmt element)))
+   ((org-src-edit-buffer-p) (org-src-do-at-code-block (org-src-coderef-format)))
+   ((org-element-property :label-fmt (org-element-at-point)))
+   (t org-coderef-label-format)))
+
+(defun org-src-coderef-regexp (fmt &optional label)
+  "Return regexp matching a coderef format string FMT.
+
+When optional argument LABEL is non-nil, match coderef for that
+label only.
 
 Match group 1 contains the full coderef string with surrounding
 white spaces.  Match group 2 contains the same string without any
-surrounding space.  Match group 3 contains the label."
-  (let ((label (regexp-quote (or (org-element-property :label-fmt element)
-				 org-coderef-label-format))))
-    (format "\\S-\\([ \t]*\\(%s\\)[ \t]*\\)$"
-	    (replace-regexp-in-string
-	     "%s" "\\([-a-zA-Z0-9_ ]+\\)" label nil t))))
+surrounding space.  Match group 3 contains the label.
+
+A coderef format regexp can only match at the end of a line."
+  (format "\\S-\\([ \t]*\\(%s\\)[ \t]*\\)$"
+	  (replace-regexp-in-string
+	   "%s"
+	   (if label (regexp-quote label) "\\([-a-zA-Z0-9_ ]+\\)")
+	   (regexp-quote fmt)
+	   nil t)))
 
 (defun org-edit-footnote-reference ()
   "Edit definition of footnote reference at point."

+ 4 - 3
lisp/ox.el

@@ -79,8 +79,9 @@
 (declare-function org-publish "ox-publish" (project &optional force async))
 (declare-function org-publish-all "ox-publish" (&optional force async))
 (declare-function org-publish-current-file "ox-publish" (&optional force async))
-(declare-function org-publish-current-project "ox-publish"
-		  (&optional force async))
+(declare-function org-publish-current-project "ox-publish" (&optional force async))
+(declare-function org-src-coderef-format "org-src" (&optional element))
+(declare-function org-src-coderef-regexp "org-src" (fmt &optional label))
 
 (defvar org-publish-project-alist)
 (defvar org-table-number-fraction)
@@ -4531,7 +4532,7 @@ reference on that line (string)."
 		     value
 		   (org-remove-indentation value)))))
 	 ;; Build a regexp matching a loc with a reference.
-	 (ref-re (org-src-coderef-regexp element)))
+	 (ref-re (org-src-coderef-regexp (org-src-coderef-format element))))
     ;; Return value.
     (cons
      ;; Code with references removed.

+ 104 - 0
testing/lisp/test-org-src.el

@@ -133,5 +133,109 @@ This is a tab:\t.
               (org-edit-src-exit)
               (buffer-string))))))
 
+(ert-deftest test-org-src/coderef-format ()
+  "Test `org-src-coderef-format' specifications."
+  ;; Regular tests in a src block, an example block and an edit
+  ;; buffer.
+  (should
+   (equal "foo"
+          (let ((org-coderef-label-format "foo"))
+            (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
+              (org-src-coderef-format)))))
+  (should
+   (equal "foo"
+          (let ((org-coderef-label-format "foo"))
+            (org-test-with-temp-text "#+BEGIN_EXAMPLE\n0\n#+END_EXAMPLE"
+              (org-src-coderef-format)))))
+  (should
+   (equal "foo"
+          (let ((org-coderef-label-format "foo") result)
+            (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
+              (org-edit-special)
+              (setq result (org-src-coderef-format))
+              (org-edit-src-exit)
+              result))))
+  ;; When a local variable in the source buffer is available, use it.
+  (should
+   (equal "bar"
+          (let ((org-coderef-label-format "foo"))
+            (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
+              (setq-local org-coderef-label-format "bar")
+              (org-src-coderef-format)))))
+  (should
+   (equal "bar"
+          (let ((org-coderef-label-format "foo") result)
+            (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
+              (setq-local org-coderef-label-format "bar")
+              (org-edit-special)
+              (setq result (org-src-coderef-format))
+              (org-edit-src-exit)
+              result))))
+  ;; Use provided local format even if in an edit buffer.
+  (should
+   (equal "bar"
+          (let ((org-coderef-label-format "foo"))
+            (org-test-with-temp-text
+		"#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
+              (org-src-coderef-format)))))
+  (should
+   (equal "bar"
+          (let ((org-coderef-label-format "foo") result)
+            (org-test-with-temp-text
+                "#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
+              (org-edit-special)
+              (setq result (org-src-coderef-format))
+              (org-edit-src-exit)
+              result))))
+  ;; Local format has precedence over local variables.
+  (should
+   (equal "bar"
+          (let ((org-coderef-label-format "foo"))
+            (org-test-with-temp-text
+		"#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
+	      (setq-local org-coderef-label-format "foo")
+              (org-src-coderef-format)))))
+  (should
+   (equal "bar"
+          (let ((org-coderef-label-format "foo") result)
+            (org-test-with-temp-text
+                "#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
+	      (setq-local org-coderef-label-format "foo")
+              (org-edit-special)
+              (setq result (org-src-coderef-format))
+              (org-edit-src-exit)
+              result))))
+  ;; When optional argument provides a coderef format string, use it.
+  (should
+   (equal "bar"
+	  (let ((org-coderef-label-format "foo")
+		(element (org-element-create 'src-block '(:label-fmt "bar"))))
+	    (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
+	      (org-src-coderef-format element)))))
+  (should
+   (equal "baz"
+          (let ((org-coderef-label-format "foo")
+		(element (org-element-create 'src-block '(:label-fmt "baz"))))
+            (org-test-with-temp-text
+		"#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
+	      (setq-local org-coderef-label-format "foo")
+              (org-src-coderef-format element)))))
+  ;; If it doesn't provide any label format string, fall back to
+  ;; regular checks.
+  (should
+   (equal "foo"
+	  (let ((org-coderef-label-format "foo")
+		(element (org-element-create 'src-block)))
+	    (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
+	      (org-src-coderef-format element)))))
+  (should
+   (equal "bar"
+          (let ((org-coderef-label-format "foo")
+		(element (org-element-create 'src-block)))
+            (org-test-with-temp-text
+		"#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
+	      (setq-local org-coderef-label-format "foo")
+              (org-src-coderef-format element))))))
+
 (provide 'test-org-src)
 ;;; test-org-src.el ends here