emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Nicolas Goaziou <n.goaziou@gmail.com>
To: Alan Schmitt <alan.schmitt@polytechnique.org>
Cc: emacs-orgmode@gnu.org
Subject: Re: bug with :wrap when exporting
Date: Wed, 04 Dec 2013 23:29:25 +0100	[thread overview]
Message-ID: <87eh5suu62.fsf@gmail.com> (raw)
In-Reply-To: <m2k3fkbxec.fsf@polytechnique.org> (Alan Schmitt's message of "Wed, 04 Dec 2013 13:42:19 +0100")

[-- Attachment #1: Type: text/plain, Size: 910 bytes --]

Hello,

Alan Schmitt <alan.schmitt@polytechnique.org> writes:

> I think I have found a bug with ":wrap" when exporting a block. Consider
> the following org file:
>
> #+name: mywrap
> #+BEGIN_SRC sh :exports none :results raw
> echo "(+ 1 2)"
> #+END_SRC
>
> Exporting with the result absent:
>
> #+name: testmywrap
> #+call: mywrap() :wrap src emacs-lisp
>
> #+results: testmywrap
>
> Exporting with the result present:
>
> #+name: testmywrap2
> #+call: mywrap() :wrap src emacs-lisp
>
> #+results: testmywrap2
> #+BEGIN_src emacs-lisp
> (+ 1 2)
> #+END_src
>
> If you export it, you'll see that the results for the second call are
> duplicated. Note that this only happens during export: evaluating the
> second call to mywrap does not duplicate the results below.

The following patch (from maint) fixed the problem shown in the ECM.
Does it still work in the general case?


Regards,

-- 
Nicolas Goaziou

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ob-exp-Fix-duplicate-evaluation-with-wrap-src.patch --]
[-- Type: text/x-diff, Size: 12130 bytes --]

From 2b79fc4f9940abfd97d83103ab1de39cf2c44ede Mon Sep 17 00:00:00 2001
From: Nicolas Goaziou <n.goaziou@gmail.com>
Date: Wed, 4 Dec 2013 23:23:33 +0100
Subject: [PATCH] ob-exp: Fix duplicate evaluation with :wrap src

* lisp/ob-exp.el (org-babel-exp-process-buffer): Fix duplicate
  evaluation with :wrap src.
(org-babel-exp-non-block-elements): Removed function.
* testing/lisp/test-ob-lob.el (test-ob-lob/export-lob-lines): Fix test.
---
 lisp/ob-exp.el              | 266 ++++++++++++++++++++------------------------
 testing/lisp/test-ob-lob.el |   1 +
 2 files changed, 119 insertions(+), 148 deletions(-)

diff --git a/lisp/ob-exp.el b/lisp/ob-exp.el
index d6d4566..746504e 100644
--- a/lisp/ob-exp.el
+++ b/lisp/ob-exp.el
@@ -150,19 +150,17 @@ this template."
   :type 'string)
 
 (defvar org-babel-default-lob-header-args)
-(defun org-babel-exp-non-block-elements (start end)
-  "Process inline source and call lines between START and END for export."
+(defun org-babel-exp-process-buffer ()
+  "Execute all Babel blocks in current buffer."
   (interactive)
-  (save-excursion
-    (goto-char start)
-    (unless (markerp end)
-      (let ((m (make-marker)))
-	(set-marker m end (current-buffer))
-	(setq end m)))
-    (let ((rx (concat "\\(?:"  org-babel-inline-src-block-regexp
-		      "\\|" org-babel-lob-one-liner-regexp "\\)")))
-      (while (re-search-forward rx end t)
-	(save-excursion
+  (save-window-excursion
+    (save-excursion
+      (let ((case-fold-search t)
+	    (regexp (concat org-babel-inline-src-block-regexp "\\|"
+			    org-babel-lob-one-liner-regexp "\\|"
+			    "^[ \t]*#\\+BEGIN_SRC")))
+	(goto-char (point-min))
+	(while (re-search-forward regexp nil t)
 	  (let* ((element (save-excursion
 			    ;; If match is inline, point is at its
 			    ;; end.  Move backward so
@@ -170,145 +168,117 @@ this template."
 			    ;; object, not the following one.
 			    (backward-char)
 			    (save-match-data (org-element-context))))
-		 (type (org-element-type element)))
-	    (when (memq type '(babel-call inline-babel-call inline-src-block))
-	      (let ((beg-el (org-element-property :begin element))
-		    (end-el (org-element-property :end element)))
-		(case type
-		  (inline-src-block
-		   (let* ((info (org-babel-parse-inline-src-block-match))
-			  (params (nth 2 info)))
-		     (setf (nth 1 info)
-			   (if (and (cdr (assoc :noweb params))
-				    (string= "yes" (cdr (assoc :noweb params))))
-			       (org-babel-expand-noweb-references
-				info (org-babel-exp-get-export-buffer))
-			     (nth 1 info)))
-		     (goto-char beg-el)
-		     (let ((replacement (org-babel-exp-do-export info 'inline)))
-		       (if (equal replacement "")
-			   ;; Replacement code is empty: completely
-			   ;; remove inline src block, including extra
-			   ;; white space that might have been created
-			   ;; when inserting results.
-			   (delete-region beg-el
-					  (progn (goto-char end-el)
-						 (skip-chars-forward " \t")
-						 (point)))
-			 ;; Otherwise: remove inline src block but
-			 ;; preserve following white spaces.  Then
-			 ;; insert value.
-			 (delete-region beg-el
-					(progn (goto-char end-el)
-					       (skip-chars-backward " \t")
-					       (point)))
-			 (insert replacement)))))
-		  ((babel-call inline-babel-call)
-		   (let* ((lob-info (org-babel-lob-get-info))
-			  (results
-			   (org-babel-exp-do-export
-			    (list "emacs-lisp" "results"
-				  (apply #'org-babel-merge-params
-					 org-babel-default-header-args
-					 org-babel-default-lob-header-args
-					 (append
-					  (org-babel-params-from-properties)
-					  (list
-					   (org-babel-parse-header-arguments
-					    (org-no-properties
-					     (concat
-					      ":var results="
-					      (mapconcat 'identity
-							 (butlast lob-info 2)
-							 " ")))))))
-				  "" (nth 3 lob-info) (nth 2 lob-info))
-			    'lob))
-			  (rep (org-fill-template
-				org-babel-exp-call-line-template
-				`(("line"  . ,(nth 0 lob-info))))))
-		     ;; If replacement is empty, completely remove the
-		     ;; object/element, including any extra white space
-		     ;; that might have been created when including
-		     ;; results.
-		     (if (equal rep "")
-			 (delete-region
-			  beg-el
-			  (progn (goto-char end-el)
-				 (if (not (eq type 'babel-call))
-				     (progn (skip-chars-forward " \t") (point))
-				   (skip-chars-forward " \r\t\n")
-				   (line-beginning-position))))
-		       ;; Otherwise, preserve following white
-		       ;; spaces/newlines and then, insert replacement
-		       ;; string.
-		       (goto-char beg-el)
+		 (type (org-element-type element))
+		 (beg-el (org-element-property :begin element))
+		 (end-el (org-element-property :end element)))
+	    (case type
+	      (inline-src-block
+	       (let* ((info (org-babel-parse-inline-src-block-match))
+		      (params (nth 2 info)))
+		 (setf (nth 1 info)
+		       (if (and (cdr (assoc :noweb params))
+				(string= "yes" (cdr (assoc :noweb params))))
+			   (org-babel-expand-noweb-references
+			    info (org-babel-exp-get-export-buffer))
+			 (nth 1 info)))
+		 (goto-char beg-el)
+		 (let ((replacement (org-babel-exp-do-export info 'inline)))
+		   (if (equal replacement "")
+		       ;; Replacement code is empty: remove inline src
+		       ;; block, including extra white space that
+		       ;; might have been created when inserting
+		       ;; results.
 		       (delete-region beg-el
 				      (progn (goto-char end-el)
-					     (skip-chars-backward " \r\t\n")
+					     (skip-chars-forward " \t")
 					     (point)))
-		       (insert rep)))))))))))))
-
-(defvar org-src-preserve-indentation)	; From org-src.el
-(defun org-babel-exp-process-buffer ()
-  "Execute all blocks in visible part of buffer."
-  (interactive)
-  (save-window-excursion
-    (let ((case-fold-search t)
-	  (pos (point-min)))
-      (goto-char pos)
-      (while (re-search-forward "^[ \t]*#\\+BEGIN_SRC" nil t)
-        (let ((element (save-match-data (org-element-at-point))))
-          (when (eq (org-element-type element) 'src-block)
-            (let* ((match-start (copy-marker (match-beginning 0)))
-                   (begin (copy-marker (org-element-property :begin element)))
-                   ;; Make sure we don't remove any blank lines after
-                   ;; the block when replacing it.
-                   (block-end (save-excursion
-				(goto-char (org-element-property :end element))
-				(skip-chars-backward " \r\t\n")
-				(copy-marker (line-end-position))))
-                   (ind (org-get-indentation))
-                   (headers
-		    (cons
-		     (org-element-property :language element)
-		     (let ((params (org-element-property :parameters element)))
-		       (and params (org-split-string params "[ \t]+"))))))
-              ;; Execute all non-block elements between POS and
-              ;; current block.
-              (org-babel-exp-non-block-elements pos begin)
-	      ;; Take care of matched block: compute replacement
-	      ;; string. In particular, a nil REPLACEMENT means the
-	      ;; block should be left as-is while an empty string
-	      ;; should remove the block.
-              (let ((replacement (progn (goto-char match-start)
-					(org-babel-exp-src-block headers))))
-                (cond ((not replacement) (goto-char block-end))
-		      ((equal replacement "")
-		       (delete-region begin
-				      (progn (goto-char block-end)
-					     (skip-chars-forward " \r\t\n")
-					     (if (eobp) (point)
-					       (line-beginning-position)))))
-		      (t
-		       (goto-char match-start)
-		       (delete-region (point) block-end)
-		       (insert replacement)
-		       (if (org-element-property :preserve-indent element)
-			   ;; Indent only the code block markers.
-			   (save-excursion (skip-chars-backward " \r\t\n")
-					   (indent-line-to ind)
-					   (goto-char match-start)
-					   (indent-line-to ind))
-			 ;; Indent everything.
-			 (indent-rigidly match-start (point) ind)))))
-	      (setq pos (line-beginning-position))
-              ;; Cleanup markers.
-	      (set-marker match-start nil)
-	      (set-marker begin nil)
-              (set-marker block-end nil)))))
-      ;; Eventually execute all non-block Babel elements between last
-      ;; src-block and end of buffer.
-      (org-babel-exp-non-block-elements pos (point-max)))))
+		     ;; Otherwise: remove inline src block but
+		     ;; preserve following white spaces.  Then insert
+		     ;; value.
+		     (delete-region beg-el
+				    (progn (goto-char end-el)
+					   (skip-chars-backward " \t")
+					   (point)))
+		     (insert replacement)))))
+	      ((babel-call inline-babel-call)
+	       (let* ((lob-info (org-babel-lob-get-info))
+		      (results
+		       (org-babel-exp-do-export
+			(list "emacs-lisp" "results"
+			      (apply #'org-babel-merge-params
+				     org-babel-default-header-args
+				     org-babel-default-lob-header-args
+				     (append
+				      (org-babel-params-from-properties)
+				      (list
+				       (org-babel-parse-header-arguments
+					(org-no-properties
+					 (concat
+					  ":var results="
+					  (mapconcat 'identity
+						     (butlast lob-info 2)
+						     " ")))))))
+			      "" (nth 3 lob-info) (nth 2 lob-info))
+			'lob))
+		      (rep (org-fill-template
+			    org-babel-exp-call-line-template
+			    `(("line"  . ,(nth 0 lob-info))))))
+		 ;; If replacement is empty, completely remove the
+		 ;; object/element, including any extra white space
+		 ;; that might have been created when including
+		 ;; results.
+		 (if (equal rep "")
+		     (delete-region
+		      beg-el
+		      (progn (goto-char end-el)
+			     (if (not (eq type 'babel-call))
+				 (progn (skip-chars-forward " \t") (point))
+			       (skip-chars-forward " \r\t\n")
+			       (line-beginning-position))))
+		   ;; Otherwise, preserve following white
+		   ;; spaces/newlines and then, insert replacement
+		   ;; string.
+		   (goto-char beg-el)
+		   (delete-region beg-el
+				  (progn (goto-char end-el)
+					 (skip-chars-backward " \r\t\n")
+					 (point)))
+		   (insert rep))))
+	      (src-block
+	       (let* ((match-start (match-beginning 0))
+		      ;; Make sure we don't remove any blank lines
+		      ;; after the block when replacing it.
+		      (block-end (save-excursion
+				   (goto-char end-el)
+				   (skip-chars-backward " \r\t\n")
+				   (line-end-position)))
+		      (ind (org-get-indentation))
+		      (headers
+		       (cons
+			(org-element-property :language element)
+			(let ((params (org-element-property :parameters element)))
+			  (and params (org-split-string params "[ \t]+"))))))
+		 ;; Take care of matched block: compute replacement
+		 ;; string.  In particular, a nil REPLACEMENT means
+		 ;; the block should be left as-is while an empty
+		 ;; string should remove the block.
+		 (let ((replacement (progn (goto-char match-start)
+					   (org-babel-exp-src-block headers))))
+		   (cond ((not replacement) (goto-char block-end))
+			 ((equal replacement "")
+			  (delete-region beg-el end-el))
+			 (t
+			  (goto-char match-start)
+			  (delete-region (point) block-end)
+			  (insert replacement)
+			  (if (org-element-property :preserve-indent element)
+			      ;; Indent only the code block markers.
+			      (save-excursion (skip-chars-backward " \r\t\n")
+					      (indent-line-to ind)
+					      (goto-char match-start)
+					      (indent-line-to ind))
+			    ;; Indent everything.
+			    (indent-rigidly match-start (point) ind))))))))))))))
 
 (defun org-babel-in-example-or-verbatim ()
   "Return true if point is in example or verbatim code.
diff --git a/testing/lisp/test-ob-lob.el b/testing/lisp/test-ob-lob.el
index db3b7c8..828eef2 100644
--- a/testing/lisp/test-ob-lob.el
+++ b/testing/lisp/test-ob-lob.el
@@ -86,6 +86,7 @@
 	(let ((org-current-export-file buf))
 	  (org-babel-exp-process-buffer))
 	(message (buffer-string))
+	(goto-char (point-min))
 	(should (re-search-forward "^: 0" nil t))
 	(should (re-search-forward "call =2= stuck" nil t))
 	(should (re-search-forward
-- 
1.8.4.2


  reply	other threads:[~2013-12-04 22:29 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-04 12:42 bug with :wrap when exporting Alan Schmitt
2013-12-04 22:29 ` Nicolas Goaziou [this message]
2013-12-05 12:43   ` Alan Schmitt
2013-12-05 15:23     ` Josiah Schwab
2013-12-05 17:10       ` Alan Schmitt
2013-12-05 17:57         ` Nick Dokos
2013-12-06  8:32           ` Sebastien Vauban
2013-12-05 17:52     ` Alan Schmitt
2013-12-05 20:27       ` Achim Gratz
2013-12-06 15:29         ` Alan Schmitt
2013-12-06 15:32   ` Alan Schmitt
2013-12-06 15:44     ` Nicolas Goaziou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87eh5suu62.fsf@gmail.com \
    --to=n.goaziou@gmail.com \
    --cc=alan.schmitt@polytechnique.org \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).