Org-mode mailing list
 help / color / mirror / Atom feed
From: Jack Kamm <jackkamm@gmail.com>
To: "Berry, Charles" <ccberry@health.ucsd.edu>
Cc: "emacs-orgmode@gnu.org" <emacs-orgmode@gnu.org>,
	Dylan Schwilk <dylan@schwilk.org>
Subject: Re: Help debugging R source code block output problem with :session
Date: Mon, 07 Sep 2020 01:18:55 -0700
Message-ID: <87tuwa9ez4.fsf@gmail.com> (raw)
In-Reply-To: <352C7149-743F-4944-ACA5-7A1242B5A3AA@health.ucsd.edu>

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

Hi Chuck and Dylan,

"Berry, Charles" <ccberry@health.ucsd.edu> writes:

> This problem has been bugging people for years and previous attempts to solve it have always run up against creating more problems in the process of solving this one.
>
> If you do decide to dig into solving this, please be sure that remote sessions and graphical outputs are not broken.  test-ob-R.el does not cover those cases.  In fact, it is pretty short, so there are probably other things that could break without `make test' complaining.

I think I have found a robust solution to this issue, which I've
attached.

The solution avoids parsing for prompts at all, thus it should be robust
even for the case when the beginning of an output line looks like a
prompt.

I tested that the unit tests all pass, and that remote sessions and
graphical outputs still work. I also added Dylan's examples as unit
tests.

Cheers,
Jack


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ob-R-Fix-session-output-with-substrings-matching-pro.patch --]
[-- Type: text/x-patch, Size: 4277 bytes --]

From 76d0eaa31506ce8a2f81f64eae43161db5721317 Mon Sep 17 00:00:00 2001
From: Jack Kamm <jackkamm@gmail.com>
Date: Mon, 7 Sep 2020 00:41:52 -0700
Subject: [PATCH] ob-R: Fix session output with substrings matching prompts

* lisp/ob-R.el (ess-send-string): Declare external function.
(org-babel-R-evaluate-session): New implementation for session output
results, that replaces calls to org-babel-comint-with-output with
custom code.
* testing/lisp/test-ob-R.el (test-ob-R/prompt-output): New test for
output results containing angle brackets.
(test-ob-R/output-nonprinted): New test for output results that aren't
explicitly printed.

Fixes issue reported in
https://orgmode.org/list/875zgjh8wn.fsf@gmail.com/,
https://orgmode.org/list/87r1rqled0.fsf@havana/
---
 lisp/ob-R.el              | 37 +++++++++++++++++++------------------
 testing/lisp/test-ob-R.el | 13 +++++++++++++
 2 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/lisp/ob-R.el b/lisp/ob-R.el
index 5e9d35f58..b37e3965a 100644
--- a/lisp/ob-R.el
+++ b/lisp/ob-R.el
@@ -38,6 +38,8 @@ (declare-function ess-make-buffer-current "ext:ess-inf" ())
 (declare-function ess-eval-buffer "ext:ess-inf" (vis))
 (declare-function ess-wait-for-process "ext:ess-inf"
 		  (&optional proc sec-prompt wait force-redisplay))
+(declare-function ess-send-string "ext:ess-inf"
+		  (process string &optional visibly message _type))
 
 (defconst org-babel-header-args:R
   '((width		 . :any)
@@ -437,24 +439,23 @@ (defun org-babel-R-evaluate-session
 	  (org-babel-import-elisp-from-file tmp-file '(16)))
 	column-names-p)))
     (output
-     (mapconcat
-      'org-babel-chomp
-      (butlast
-       (delq nil
-	     (mapcar
-	      (lambda (line) (when (> (length line) 0) line))
-	      (mapcar
-	       (lambda (line) ;; cleanup extra prompts left in output
-		 (if (string-match
-		      "^\\([>+.]\\([ ][>.+]\\)*[ ]\\)"
-		      (car (split-string line "\n")))
-		     (substring line (match-end 1))
-		   line))
-	       (org-babel-comint-with-output (session org-babel-R-eoe-output)
-		 (insert (mapconcat 'org-babel-chomp
-				    (list body org-babel-R-eoe-indicator)
-				    "\n"))
-		 (inferior-ess-send-input)))))) "\n"))))
+     (let* ((tmp-file (org-babel-temp-file "R-")))
+       (with-temp-file tmp-file
+	 (insert (concat body "\n" org-babel-R-eoe-indicator)))
+       (with-current-buffer session
+	 (let* ((process (get-buffer-process (current-buffer)))
+		(string-buffer "")
+		(comint-output-filter-functions
+		 (cons (lambda (text) (setq string-buffer
+					    (concat string-buffer text)))
+		       comint-output-filter-functions)))
+	   (ess-send-string
+	    process (format "source('%s', print.eval=TRUE)"
+			    (org-babel-process-file-name tmp-file 'noquote)))
+	   (while (not (string-match (regexp-quote org-babel-R-eoe-output)
+				     string-buffer))
+	     (accept-process-output process))
+	   (substring string-buffer 0 (match-beginning 0))))))))
 
 (defun org-babel-R-process-value-result (result column-names-p)
   "R-specific processing of return value.
diff --git a/testing/lisp/test-ob-R.el b/testing/lisp/test-ob-R.el
index 7ce340ba4..ff7ea19d5 100644
--- a/testing/lisp/test-ob-R.el
+++ b/testing/lisp/test-ob-R.el
@@ -97,6 +97,19 @@ (ert-deftest test-ob-R/results-file ()
      (org-babel-goto-named-result "TESTSRC") (forward-line 1)
      (should (string= "[[file:junk/test.org]]"
 		      (buffer-substring-no-properties (point-at-bol) (point-at-eol)))))))
+
+(ert-deftest test-ob-R/prompt-output ()
+  (let (ess-ask-for-ess-directory ess-history-file)
+    (org-test-with-temp-text
+     "#+begin_src R :results output :session\nprint(\"<X> <Y> <!>\")\nprint(\"one <two> three\")\nprint(\"end\")\n#+end_src\n"
+     (should (string= "[1] \"<X> <Y> <!>\"\n[1] \"one <two> three\"\n[1] \"end\"\n" (org-babel-execute-src-block))))))
+
+(ert-deftest test-ob-R/output-nonprinted ()
+  (let (ess-ask-for-ess-directory ess-history-file)
+    (org-test-with-temp-text
+     "#+begin_src R :results output :session\n4.0 * 3.5\nlog(10)\nlog10(10)\n(3 + 1) * 5\n3^-1\n1/0\n#+end_src\n"
+     (should (string= "[1] 14\n[1] 2.302585\n[1] 1\n[1] 20\n[1] 0.3333333\n[1] Inf\n" (org-babel-execute-src-block))))))
+
 (provide 'test-ob-R)
 
 ;;; test-ob-R.el ends here
-- 
2.28.0


  parent reply	other threads:[~2020-09-07  8:19 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-28 20:11 Dylan Schwilk
2020-08-29  2:36 ` Jack Kamm
2020-08-29  4:07   ` Dylan Schwilk
2020-08-29  7:24     ` Jack Kamm
2020-08-29 20:35       ` Berry, Charles via General discussions about Org-mode.
2020-08-30  4:37         ` Dylan Schwilk
2020-08-30 15:08         ` Jack Kamm
2020-09-07  8:18         ` Jack Kamm [this message]
2020-09-07  8:45           ` Jack Kamm
2020-09-07 17:37             ` Berry, Charles via General discussions about Org-mode.
2020-09-07 20:07               ` Jack Kamm
2020-09-07 22:12                 ` Berry, Charles via General discussions about Org-mode.
2020-09-08  1:06                   ` Jack Kamm
2020-09-08  2:08                     ` Berry, Charles via General discussions about Org-mode.
2020-09-08 14:51                       ` Jack Kamm
2020-09-08 16:45                         ` Berry, Charles via General discussions about Org-mode.
2020-09-08 17:41                           ` Jack Kamm
2020-09-18 16:39                             ` Dylan Schwilk
2020-10-28 13:13                 ` Jack Kamm
2020-10-28 13:46                   ` Jeremie Juste
2020-08-30  4:18       ` Dylan Schwilk
2021-05-03  8:53       ` Jeremie Juste

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://orgmode.org

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

  git send-email \
    --in-reply-to=87tuwa9ez4.fsf@gmail.com \
    --to=jackkamm@gmail.com \
    --cc=ccberry@health.ucsd.edu \
    --cc=dylan@schwilk.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

Org-mode mailing list

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://orgmode.org/list/0 list/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 list list/ https://orgmode.org/list \
		emacs-orgmode@gnu.org
	public-inbox-index list

Example config snippet for mirrors.
Newsgroups are available over NNTP:
	nntp://news.yhetil.org/yhetil.emacs.orgmode
	nntp://news.gmane.io/gmane.emacs.orgmode


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git