浏览代码

ob: Support for exporting inline source code

* lisp/ob-exp.el (org-babel-exp-inline-code-template): New
customizable variable to export inline source code (similar to
`org-babel-exp-code-template').
(org-babel-exp-code): New `type' argument to differentiate between
inline and standard code blocks.

* lisp/ob-core.el (org-babel-inline-src-block-regexp): Allow empty set
of switches and header arguments as in "src_sh[]{echo foo;}".  Also
permit spaces before them.

* testint/lisp/test-org-element.el
(test-org-element/inline-src-block-parser): Test extended syntax for
inline source code.

* testing/lisp/test-ob-exp.el (ob-exp/exports-inline-code): New
function for testing inline source code handling.  Also add three new
failing tests exhibiting unexpected results with ":results code"
switches.

* testing/lisp/test-ob.el
(test-org-babel/org-babel-get-inline-src-block-matches): Test for
inline source blocks with empty header arguments.

* testing/examples/babel.org: New sections for testing (i) exported
inline source code (used by `ob-exp/exports-inline-code'); (ii)
parsing inline source blocks with empty header arguments (used by
`test-org-babel/org-babel-get-inline-src-block-matches').

Until now pieces of inline source code were handled as standard code
blocks during export.  These changes enable them to be exported.
Nicolas Berthier 10 年之前
父节点
当前提交
795c004396
共有 6 个文件被更改,包括 208 次插入36 次删除
  1. 2 2
      lisp/ob-core.el
  2. 28 4
      lisp/ob-exp.el
  3. 22 0
      testing/examples/babel.org
  4. 93 0
      testing/lisp/test-ob-exp.el
  5. 41 30
      testing/lisp/test-ob.el
  6. 22 0
      testing/lisp/test-org-element.el

+ 2 - 2
lisp/ob-core.el

@@ -203,9 +203,9 @@ This string must include a \"%s\" which will be replaced by the results."
 (defvar org-babel-inline-src-block-regexp
   (concat
    ;; (1) replacement target (2) lang
-   "\\(?:^\\|[^-[:alnum:]]\\)\\(src_\\([^ \f\t\n\r\v]+\\)"
+   "\\(?:^\\|[^-[:alnum:]]\\)\\(src_\\([^ \f\t\n\r\v[]+\\)"
    ;; (3,4) (unused, headers)
-   "\\(\\|\\[\\(.*?\\)\\]\\)"
+   "\\(\\|\\[[ \t]*\\(.*?\\)\\]\\)"
    ;; (5) body
    "{\\([^\f\n\r\v]+?\\)}\\)")
   "Regexp used to identify inline src-blocks.")

+ 28 - 4
lisp/ob-exp.el

@@ -318,10 +318,10 @@ The function respects the value of the :exports header argument."
 	(clean (lambda () (unless (eq type 'inline) (org-babel-remove-result info)))))
     (case (intern (or (cdr (assoc :exports (nth 2 info))) "code"))
       ('none (funcall silently) (funcall clean) "")
-      ('code (funcall silently) (funcall clean) (org-babel-exp-code info))
+      ('code (funcall silently) (funcall clean) (org-babel-exp-code info type))
       ('results (org-babel-exp-results info type nil hash) "")
       ('both (org-babel-exp-results info type nil hash)
-	     (org-babel-exp-code info)))))
+	     (org-babel-exp-code info type)))))
 
 (defcustom org-babel-exp-code-template
   "#+BEGIN_SRC %lang%switches%flags\n%body\n#+END_SRC"
@@ -343,7 +343,29 @@ replaced with its value."
   :group 'org-babel
   :type 'string)
 
-(defun org-babel-exp-code (info)
+(defcustom org-babel-exp-inline-code-template
+  "src_%lang[%switches%flags]{%body}"
+  "Template used to export the body of inline code blocks.
+This template may be customized to include additional information
+such as the code block name, or the values of particular header
+arguments.  The template is filled out using `org-fill-template',
+and the following %keys may be used.
+
+ lang ------ the language of the code block
+ name ------ the name of the code block
+ body ------ the body of the code block
+ switches -- the switches associated to the code block
+ flags ----- the flags passed to the code block
+
+In addition to the keys mentioned above, every header argument
+defined for the code block may be used as a key and will be
+replaced with its value."
+  :group 'org-babel
+  :type 'string
+  :version "24.5"
+  :package-version '(Org . "8.3"))
+
+(defun org-babel-exp-code (info type)
   "Return the original code block formatted for export."
   (setf (nth 1 info)
 	(if (string= "strip-export" (cdr (assoc :noweb (nth 2 info))))
@@ -354,7 +376,9 @@ replaced with its value."
 	       info org-babel-exp-reference-buffer)
 	    (nth 1 info))))
   (org-fill-template
-   org-babel-exp-code-template
+   (if (eq type 'inline)
+       org-babel-exp-inline-code-template 
+       org-babel-exp-code-template)
    `(("lang"  . ,(nth 0 info))
      ("body"  . ,(org-escape-code-in-string (nth 1 info)))
      ("switches" . ,(let ((f (nth 3 info)))

+ 22 - 0
testing/examples/babel.org

@@ -200,6 +200,17 @@ Here is one in the middle src_sh{echo 1} of a line.
 Here is one at the end of a line. src_sh{echo 2}
 src_sh{echo 3} Here is one at the beginning of a line.
 
+* exported inline source block
+:PROPERTIES:
+:ID:       cd54fc88-1b6b-45b6-8511-4d8fa7fc8076
+:results:  silent
+:exports:  code
+:END:
+Here is one in the middle src_sh{echo 1} of a line.
+Here is one at the end of a line. src_sh{echo 2}
+src_sh{echo 3} Here is one at the beginning of a line.
+Here is one that is also evaluated: src_sh[:exports both]{echo 4}
+
 * mixed blocks with exports both
   :PROPERTIES:
   :ID:       5daa4d03-e3ea-46b7-b093-62c1b7632df3
@@ -283,6 +294,17 @@ src_sh{echo "One"} block at start of line
  One spaced block in  src_sh{ echo "middle" } of line
 src_sh{echo 2} blocks on the src_emacs-lisp{"same"} line
  Inline block with src_sh[:results silent]{ echo "parameters" }.
+
+* org-babel-get-inline-src-block-matches (with empty args)
+  :PROPERTIES:
+  :results:  silent
+  :ID:       d55dada7-de0e-4340-8061-787cccbedee5
+  :END:
+src_sh[]{echo "One"} block at start of line
+ One spaced block in  src_sh[]{ echo "middle" } of line
+src_sh[]{echo 2} blocks on the src_emacs-lisp[]{"same"} line
+ Inline block with src_sh[:results silent]{ echo "parameters" }.
+
 * exporting a code block with a name
   :PROPERTIES:
   :ID:       b02ddd8a-eeb8-42ab-8664-8a759e6f43d9

+ 93 - 0
testing/lisp/test-ob-exp.el

@@ -197,6 +197,99 @@ Here is one at the end of a line. =2=
       (org-narrow-to-subtree)
       (org-test-with-expanded-babel-code (buffer-string))))))
 
+(ert-deftest ob-exp/exports-inline-code ()
+  (should
+   (string-match "\\`src_emacs-lisp\\(?:\\[]\\)?{(\\+ 1 1)}$"
+		 (org-test-with-temp-text
+		  "src_emacs-lisp[:exports code]{(+ 1 1)}"
+		  (org-export-execute-babel-code)
+		  (buffer-string))))
+  (should
+   (string-match "\\`src_emacs-lisp\\(?:\\[]\\)?{(\\+ 1 1)}$"
+		 (org-test-with-temp-text
+		  "src_emacs-lisp[ :exports code ]{(+ 1 1)}"
+		  (org-export-execute-babel-code)
+		  (buffer-string))))
+  (should
+   (string-match "\\`src_emacs-lisp\\(?:\\[]\\)?{(\\+ 1 1)} =2=$"
+		 (org-test-with-temp-text
+		  "src_emacs-lisp[:exports both]{(+ 1 1)}"
+		  (org-export-execute-babel-code)
+		  (buffer-string))))
+  (should
+   (string-match "\\`=2=$"
+		 (org-test-with-temp-text
+		  "src_emacs-lisp[:exports results :results scalar]{(+ 1 1)}"
+		  (org-export-execute-babel-code)
+		  (buffer-string))))
+  (should
+   (let ((text "foosrc_emacs-lisp[:exports code]{(+ 1 1)}"))
+     (string-match (regexp-quote text)
+		   (org-test-with-temp-text
+		    text
+		    (org-export-execute-babel-code)
+		    (buffer-string)))))
+  (should
+   (let ((text "src_emacs lisp{(+ 1 1)}"))
+     (string-match (regexp-quote text)
+		   (org-test-with-temp-text
+		    text
+		    (org-export-execute-babel-code)
+		    (buffer-string)))))
+  (should
+   (string-match
+    (replace-regexp-in-string
+     "\\\\\\[]{" "\\(?:\\[]\\)?{" ;accept both src_sh[]{...} or src_sh{...}
+     (regexp-quote "Here is one in the middle src_sh[]{echo 1} of a line.
+Here is one at the end of a line. src_sh[]{echo 2}
+src_sh[]{echo 3} Here is one at the beginning of a line.
+Here is one that is also evaluated: src_sh[]{echo 4} =4=")
+     nil t)
+    (org-test-at-id "cd54fc88-1b6b-45b6-8511-4d8fa7fc8076"
+      (org-narrow-to-subtree)
+      (org-test-with-expanded-babel-code (buffer-string))))))
+
+(ert-deftest ob-exp/exports-inline-code-double-eval-bug ()
+  "Failing for now as the result actually is
+`#+BEGIN_SRC emacs-lisp\n2#+END_SRC\n'.
+
+Based on default header arguments for inline code blocks (:exports
+results), the resulting code block `src_emacs-lisp{2}' should also be
+evaluated."
+  :expected-result :failed
+  (should
+   (string-match "\\`=2=$"
+  		 (org-test-with-temp-text
+  		  "src_emacs-lisp[:exports results :results code]{(+ 1 1)}"
+  		  (org-export-execute-babel-code)
+  		  (buffer-string)))))
+
+(ert-deftest ob-exp/exports-inline-code-eval-code-once-bug ()
+  "Ibid above, except that the resulting inline code block should not
+be evaluated. Result for now is
+`#+BEGIN_SRC emacs-lisp :exports code\n2#+END_SRC\n'"
+  :expected-result :failed
+  (should
+   (string-match "\\`src_emacs-lisp\\(?:\\[]\\)?{2}$"
+  		 (org-test-with-temp-text
+  		  (concat "src_emacs-lisp[:exports results :results code "
+			  ":results_switches \":exports code\"]{(+ 1 1)}")
+  		  (org-export-execute-babel-code)
+  		  (buffer-string)))))
+
+(ert-deftest ob-exp/exports-inline-code-double-eval-exports-both-bug ()
+  "Failing for now as the result actually is 
+`src_emacs-lisp[]{(+ 1 1)} #+BEGIN_SRC emacs-lisp\n2#+END_SRC\n'."
+  :expected-result :failed
+  (should
+   (string-match (concat "\\`src_emacs-lisp\\(?:\\[]\\)?{(\\+ 1 1)} "
+  			 "src_emacs-lisp\\(?:\\[]\\)?{2}$")
+  		 (org-test-with-temp-text
+  		  (concat "src_emacs-lisp[:exports both :results code "
+			  ":results_switches \":exports code\"]{(+ 1 1)}")
+  		  (org-export-execute-babel-code)
+  		  (buffer-string)))))
+
 (ert-deftest ob-exp/export-call-line-information ()
   (org-test-at-id "bec63a04-491e-4caa-97f5-108f3020365c"
     (org-narrow-to-subtree)

+ 41 - 30
testing/lisp/test-ob.el

@@ -249,38 +249,49 @@ this is simple"
     (should (= 14 (org-babel-execute-src-block)))))
 
 (ert-deftest test-org-babel/inline-src-blocks ()
-  (org-test-at-id "54cb8dc3-298c-4883-a933-029b3c9d4b18"
-    (macrolet ((at-next (&rest body)
-			`(progn
-			   (move-end-of-line 1)
-			   (re-search-forward org-babel-inline-src-block-regexp nil t)
-			   (goto-char (match-beginning 1))
-			   (save-match-data ,@body))))
-      (at-next (should (equal 1 (org-babel-execute-src-block))))
-      (at-next (should (equal 2 (org-babel-execute-src-block))))
-      (at-next (should (equal 3 (org-babel-execute-src-block)))))))
+  (macrolet ((at-next (&rest body)
+	       `(progn
+		  (move-end-of-line 1)
+		  (re-search-forward org-babel-inline-src-block-regexp nil t)
+		  (goto-char (match-beginning 1))
+		  (save-match-data ,@body))))
+    (org-test-at-id
+     "54cb8dc3-298c-4883-a933-029b3c9d4b18"
+     (at-next (should (equal 1 (org-babel-execute-src-block))))
+     (at-next (should (equal 2 (org-babel-execute-src-block))))
+     (at-next (should (equal 3 (org-babel-execute-src-block)))))
+    (org-test-at-id
+     "cd54fc88-1b6b-45b6-8511-4d8fa7fc8076"
+     (at-next (should (equal 1 (org-babel-execute-src-block))))
+     (at-next (should (equal 2 (org-babel-execute-src-block))))
+     (at-next (should (equal 3 (org-babel-execute-src-block))))
+     (at-next (should (equal 4 (org-babel-execute-src-block)))))))
 
 (ert-deftest test-org-babel/org-babel-get-inline-src-block-matches ()
-  (org-test-at-id "0D0983D4-DE33-400A-8A05-A225A567BC74"
-    (let ((test-point (point)))
-      (should (fboundp 'org-babel-get-inline-src-block-matches))
-      (should (re-search-forward "src_" nil t)) ;; 1
-      (should (org-babel-get-inline-src-block-matches))
-      (should (re-search-forward "}" nil (point-at-bol))) ;; 1
-      (should-not (org-babel-get-inline-src-block-matches))
-      (should (re-search-forward "in" nil t)) ;; 2
-      (should-not (org-babel-get-inline-src-block-matches))
-      (should (re-search-forward "echo" nil t)) ;; 2
-      (should (org-babel-get-inline-src-block-matches))
-      (should (re-search-forward "blocks" nil t)) ;; 3
-      (backward-char 8) ;; 3
-      (should (org-babel-get-inline-src-block-matches))
-      (forward-char 1) ;;3
-      (should-not (org-babel-get-inline-src-block-matches))
-      (should (re-search-forward ":results" nil t)) ;; 4
-      (should (org-babel-get-inline-src-block-matches))
-      (end-of-line)
-      (should-not (org-babel-get-inline-src-block-matches)))))
+  (flet ((test-at-id (id)
+	   (org-test-at-id 
+	    id
+	    (let ((test-point (point)))
+	      (should (fboundp 'org-babel-get-inline-src-block-matches))
+	      (should (re-search-forward "src_" nil t)) ;; 1
+	      (should (org-babel-get-inline-src-block-matches))
+	      (should (re-search-forward "}" nil (point-at-bol))) ;; 1
+	      (should-not (org-babel-get-inline-src-block-matches))
+	      (should (re-search-forward "in" nil t)) ;; 2
+	      (should-not (org-babel-get-inline-src-block-matches))
+	      (should (re-search-forward "echo" nil t)) ;; 2
+	      (should (org-babel-get-inline-src-block-matches))
+	      (should (re-search-forward "blocks" nil t)) ;; 3
+	      (backward-char 8) ;; 3
+	      (should (org-babel-get-inline-src-block-matches))
+	      (forward-char 1) ;;3
+	      (should-not (org-babel-get-inline-src-block-matches))
+	      (should (re-search-forward ":results" nil t)) ;; 4
+	      (should (org-babel-get-inline-src-block-matches))
+	      (end-of-line)
+	      (should-not (org-babel-get-inline-src-block-matches))))))
+    (test-at-id "0D0983D4-DE33-400A-8A05-A225A567BC74")
+    (test-at-id "d55dada7-de0e-4340-8061-787cccbedee5")))
 
 (ert-deftest test-org-babel/inline-src_blk-default-results-replace-line-1 ()
   (let ((test-line "src_sh{echo 1}"))

+ 22 - 0
testing/lisp/test-org-element.el

@@ -1051,6 +1051,28 @@ Some other text
   (should
    (org-test-with-temp-text "src_emacs-lisp{(+ 1 1)}"
      (org-element-map (org-element-parse-buffer) 'inline-src-block 'identity)))
+  ;; With switches.
+  (should
+   (org-test-with-temp-text "src_emacs-lisp[:foo bar]{(+ 1 1)}"
+     (org-element-map (org-element-parse-buffer) 'inline-src-block 'identity)))
+  (should
+   (org-test-with-temp-text "src_emacs-lisp[ :foo bar]{(+ 1 1)}"
+     (org-element-map (org-element-parse-buffer) 'inline-src-block 'identity)))
+  ;; Empty switches.
+  (should
+   (org-test-with-temp-text "src_emacs-lisp[]{(+ 1 1)}"
+     (org-element-map (org-element-parse-buffer) 'inline-src-block 'identity)))
+  ;; Invalid syntax.
+  (should-not
+   (org-test-with-temp-text "foosrc_emacs-lisp[]{(+ 1 1)}"
+     (org-element-map (org-element-parse-buffer) 'inline-src-block 'identity)))
+  (should-not
+   (org-test-with-temp-text "src_emacs-lisp[]foo{(+ 1 1)}"
+     (org-element-map (org-element-parse-buffer) 'inline-src-block 'identity)))
+  ;; Invalid language name
+  (should-not
+   (org-test-with-temp-text "src_emacs-\tlisp{(+ 1 1)}"
+     (org-element-map (org-element-parse-buffer) 'inline-src-block 'identity)))
   ;; Test parsing at the beginning of an item.
   (should
    (org-test-with-temp-text "- src_emacs-lisp{(+ 1 1)}"