confused about pyouts

This commit is contained in:
dickmao 2020-01-09 13:12:41 -05:00
parent 0ee5f01fe4
commit 9ac1bf62e5
9 changed files with 152 additions and 210 deletions

View file

@ -112,7 +112,7 @@ Scenario: Specific port, portless localhost refers to same, concurrent execution
And I wait for buffer to say "3.1415" And I wait for buffer to say "3.1415"
And I should not see "[....]" And I should not see "[....]"
@org @imogene
Scenario: portless url with path, image Scenario: portless url with path, image
When I open temp file "path.org" When I open temp file "path.org"
And I call "org-mode" And I call "org-mode"

View file

@ -1,3 +1,4 @@
;;; -*- lexical-binding: t; -*-
(require 'f) (require 'f)
(require 'espuds) (require 'espuds)
(require 'ert) (require 'ert)

View file

@ -42,6 +42,10 @@
(require 'ein-kernel) (require 'ein-kernel)
(require 'ein-output-area) (require 'ein-output-area)
(declare-function mm-encode-buffer "mm-encode")
(declare-function mm-possibly-verify-or-decrypt "mm-decode")
(declare-function mm-dissect-singlepart "mm-decode")
(defun ein:cell--ewoc-delete (ewoc &rest nodes) (defun ein:cell--ewoc-delete (ewoc &rest nodes)
"Delete NODES from EWOC." "Delete NODES from EWOC."
(ewoc--set-buffer-bind-dll-let* ewoc (ewoc--set-buffer-bind-dll-let* ewoc
@ -156,7 +160,6 @@ Delete current text first, thus effecting a \"refresh\"."
"Face for tooltip when using pos-tip backend." "Face for tooltip when using pos-tip backend."
:group 'ein) :group 'ein)
;;; Customization ;;; Customization
(make-obsolete-variable 'ein:enable-dynamic-javascript nil "0.17.0") (make-obsolete-variable 'ein:enable-dynamic-javascript nil "0.17.0")
@ -182,18 +185,6 @@ is on. See also `ein:connect-aotoexec-lighter'."
:type 'string :type 'string
:group 'ein) :group 'ein)
(defcustom ein:slice-image nil
"[EXPERIMENTAL] When non-`nil', use `insert-sliced-image' when
drawing images. If it is of the form of ``(ROWS COLS)``, it is
passed to the corresponding arguments of `insert-sliced-image'.
.. FIXME: ROWS and COLS must be determined dynamically by measuring
the size of iamge and Emacs window.
See also: https://github.com/tkf/emacs-ipython-notebook/issues/94"
:type 'boolean
:group 'ein)
(defcustom ein:truncate-long-cell-output nil (defcustom ein:truncate-long-cell-output nil
"When nil do not truncate cells with long outputs. When set to "When nil do not truncate cells with long outputs. When set to
a number will limit the number of lines in a cell output." a number will limit the number of lines in a cell output."
@ -209,7 +200,6 @@ a number will limit the number of lines in a cell output."
:type 'list :type 'list
:group 'ein) :group 'ein)
;;; EIEIO related utils ;;; EIEIO related utils
(defmacro ein:oset-if-empty (obj slot value) (defmacro ein:oset-if-empty (obj slot value)
@ -220,26 +210,64 @@ a number will limit the number of lines in a cell output."
`(when (slot-boundp ,obj ,slot) `(when (slot-boundp ,obj ,slot)
(slot-value ,obj ,slot))) (slot-value ,obj ,slot)))
;;; Utils ;;; Utils
(defvar ein:mime-type-map
'((image/svg+xml . svg) (image/png . png) (image/jpeg . jpeg))) (defun ein:make-mm-handle (image)
(let ((mime-type (mailcap-extension-to-mime
(symbol-name (plist-get (cdr image) :type)))))
(with-temp-buffer
(save-excursion (insert (plist-get (cdr image) :data)))
(let ((encoding (mm-encode-buffer (list mime-type))))
(mm-possibly-verify-or-decrypt
(mm-dissect-singlepart (list mime-type) encoding)
(list mime-type))))))
(defun ein:external-image-viewer (image-type)
(let (major ; Major encoding (text, etc)
minor ; Minor encoding (html, etc)
info ; Other info
major-info ; (assoc major mailcap-mime-data)
viewers ; Possible viewers
passed ; Viewers that passed the test
viewer ; The one and only viewer
(ctl (mail-header-parse-content-type (concat "image/" image-type))))
(mailcap-parse-mailcaps nil t)
(setq major (split-string (car ctl) "/"))
(setq minor (cadr major)
major (car major))
(when (setq major-info (cdr (assoc major mailcap-mime-data)))
(when (setq viewers (mailcap-possible-viewers major-info minor))
(setq info (mapcar (lambda (a)
(cons (symbol-name (car a)) (cdr a)))
(cdr ctl)))
(dolist (entry viewers)
(when (mailcap-viewer-passes-test entry info)
(push entry passed)))
(setq passed (sort (nreverse passed) 'mailcap-viewer-lessp))
;; When we want to prefer entries from the user's
;; ~/.mailcap file, then we filter out the system entries
;; and see whether we have anything left.
(when (if (boundp 'mailcap-prefer-mailcap-viewers)
mailcap-prefer-mailcap-viewers
t)
(when-let ((user-entry
(seq-find (lambda (elem)
(eq (cdr (assq 'source elem)) 'user))
passed)))
(setq passed (list user-entry))))
(setq viewer (car passed))))
(when (and (stringp (cdr (assq 'viewer viewer)))
passed)
(setq viewer (car passed)))
(mailcap-unescape-mime-test (cdr (assq 'viewer viewer)) info)))
(defun ein:insert-image (&rest args) (defun ein:insert-image (&rest args)
;; Try to insert the image, otherwise emit a warning message and proceed.
(condition-case-unless-debug err (condition-case-unless-debug err
(let* ((img (apply #'create-image args)) (let ((img (apply #'create-image args))
(buffer-undo-list t)) (buffer-undo-list t))
(if ein:slice-image (insert-image img "."))
(destructuring-bind (&optional rows cols) (error (ein:log 'warn "Could not insert image: %s" (error-message-string err)))))
(when (listp ein:slice-image) ein:slice-image)
(insert-sliced-image img "." nil (or rows 20) cols))
(insert-image img ".")))
(error (ein:log 'warn "Could not insert image: %s"
(error-message-string err))
nil)))
;;; Cell factory ;;; Cell factory
(defun ein:cell-class-from-type (type) (defun ein:cell-class-from-type (type)
@ -364,7 +392,6 @@ a number will limit the number of lines in a cell output."
for en in (ein:cell-all-element cell) for en in (ein:cell-all-element cell)
do (ein:cell--ewoc-invalidate ewoc en)))) do (ein:cell--ewoc-invalidate ewoc en))))
;;; Getter/setter ;;; Getter/setter
(cl-defmethod ein:cell-num-outputs ((cell ein:codecell)) (cl-defmethod ein:cell-num-outputs ((cell ein:codecell))
@ -430,7 +457,6 @@ Return language name as a string or `nil' when not defined.
(cl-defmethod ein:cell-language ((cell ein:htmlcell)) nil "html") (cl-defmethod ein:cell-language ((cell ein:htmlcell)) nil "html")
(cl-defmethod ein:cell-language ((cell ein:rawcell)) nil "rst") (cl-defmethod ein:cell-language ((cell ein:rawcell)) nil "rst")
;; EWOC ;; EWOC
(defun ein:cell-make-element (make-node num-outputs) (defun ein:cell-make-element (make-node num-outputs)
@ -776,7 +802,6 @@ If END is non-`nil', return the location of next element."
"Return a buffer associated by CELL (if any)." "Return a buffer associated by CELL (if any)."
(ein:aand (ein:oref-safe cell 'ewoc) (ewoc-buffer it))) (ein:aand (ein:oref-safe cell 'ewoc) (ewoc-buffer it)))
;; Data manipulation ;; Data manipulation
(cl-defmethod ein:cell-clear-output ((cell ein:codecell) stdout stderr other) (cl-defmethod ein:cell-clear-output ((cell ein:codecell) stdout stderr other)
@ -836,7 +861,7 @@ If END is non-`nil', return the location of next element."
(list 'output-stream 'output-subarea (list 'output-stream 'output-subarea
(intern (format "output-%s" (plist-get json :stream))))))) (intern (format "output-%s" (plist-get json :stream)))))))
(cl-defmethod ein:cell-append-output ((cell ein:codecell) json dynamic) (cl-defmethod ein:cell-append-output ((cell ein:codecell) json)
;; When there is a python error, we actually get two identical tracebacks back ;; When there is a python error, we actually get two identical tracebacks back
;; from the kernel, one from the "shell" channel, and one from the "iopub" ;; from the kernel, one from the "shell" channel, and one from the "iopub"
;; channel. As a workaround, we remember the cell's traceback and ignore ;; channel. As a workaround, we remember the cell's traceback and ignore
@ -847,10 +872,10 @@ If END is non-`nil', return the location of next element."
(null old-tb) (null old-tb)
(null new-tb) (null new-tb)
(not (cl-equalp new-tb old-tb))) (not (cl-equalp new-tb old-tb)))
(ein:cell-actually-append-output cell json dynamic)) (ein:cell-actually-append-output cell json))
(setf (slot-value cell 'traceback) new-tb))) (setf (slot-value cell 'traceback) new-tb)))
(cl-defmethod ein:cell-actually-append-output ((cell ein:codecell) json dynamic) (cl-defmethod ein:cell-actually-append-output ((cell ein:codecell) json)
(ein:cell-expand cell) (ein:cell-expand cell)
;; (ein:flush-clear-timeout) ;; (ein:flush-clear-timeout)
(setf (slot-value cell 'outputs) (setf (slot-value cell 'outputs)
@ -876,7 +901,7 @@ Called from ewoc pretty printer via `ein:cell-insert-output'."
(or (plist-get json :prompt_number) " ")) (or (plist-get json :prompt_number) " "))
'font-lock-face 'ein:cell-output-prompt) 'font-lock-face 'ein:cell-output-prompt)
(ein:insert-read-only "\n") (ein:insert-read-only "\n")
(ein:cell-append-mime-type json (slot-value cell 'dynamic)) (ein:cell-append-mime-type json)
(ein:insert-read-only "\n")) (ein:insert-read-only "\n"))
(cl-defmethod ein:cell-append-pyerr ((cell ein:codecell) json) (cl-defmethod ein:cell-append-pyerr ((cell ein:codecell) json)
@ -923,86 +948,33 @@ Called from ewoc pretty printer via `ein:cell-insert-output'."
(cl-defmethod ein:cell-append-display-data ((cell ein:codecell) json) (cl-defmethod ein:cell-append-display-data ((cell ein:codecell) json)
"Insert display-data type output in the buffer. "Insert display-data type output in the buffer.
Called from ewoc pretty printer via `ein:cell-insert-output'." Called from ewoc pretty printer via `ein:cell-insert-output'."
(ein:cell-append-mime-type json (slot-value cell 'dynamic)) (ein:cell-append-mime-type json)
(ein:insert-read-only "\n")) (ein:insert-read-only "\n"))
(defcustom ein:output-type-preference (make-obsolete-variable 'ein:output-type-preference nil "0.17.0")
(if (and (fboundp 'shr-insert-document)
(fboundp 'libxml-parse-xml-region))
#'ein:output-type-prefer-pretty-text-over-html
'(emacs-lisp svg image/svg+xml png image/png jpeg image/jpeg html text/html latex text/latex javascript text/javascript text text/plain))
"Output types to be used in notebook.
First output-type found in this list will be used.
This variable can be a list or a function returning a list given
DATA plist.
See also `ein:output-type-prefer-pretty-text-over-html'.
**Example**: (defsubst ein:cell-output-type (mime-type)
If you prefer HTML type over text type, you can set it as:: "Investigate why :image/svg+xml to :svg and :text/plain to :text"
(let* ((mime-str (if (symbolp mime-type) (symbol-name mime-type) mime-type))
(minor (car (nreverse (split-string mime-str "/")))))
(intern (concat ":"
(cond ((string= minor "plain") "text")
(t (intern (cl-subseq minor 0 (cl-search "+" minor)))))))))
(setq ein:output-type-preference (defun ein:cell-append-mime-type (json)
'(emacs-lisp svg png jpeg html text latex javascript)) (ein:output-area-case-type
json
Note that ``html`` comes before ``text``." (cl-case type
:type '(choice function (repeat symbol)) ((:html)
:group 'ein) (funcall (ein:output-area-get-html-renderer) value))
((:svg :png :jpeg)
(defvar ein:output-types-text-preferred (ein:insert-image (condition-case nil
'(emacs-lisp svg image/svg+xml png image/png jpeg image/jpeg text text/plain html text/html latex text/latex javascript text/javascript)) (base64-decode-string value)
(error value))
(defvar ein:output-types-html-preferred type
'(emacs-lisp svg image/svg+xml png image/png jpeg image/jpeg html text/html latex text/latex javascript text/javascript text text/plain)) t))
(otherwise
(defun ein:output-type-prefer-pretty-text-over-html (data) (ein:insert-read-only value)))))
"Use text type if it is a \"prettified\" text instead of HTML.
This is mostly for *not* using HTML table for pandas but using
HTML for other object.
If the text type output contains a newline, it is assumed be a
prettified text thus be used instead of HTML type."
(if (ein:aand (or (plist-get data :text)
(plist-get data :text/plain))
(string-match-p "\n" it))
ein:output-types-text-preferred
ein:output-types-html-preferred))
(defun ein:fix-mime-type (type)
(aif (assoc type ein:mime-type-map)
(cdr it)
type))
(defun ein:cell-append-mime-type (json dynamic)
(when (plist-get json :data)
(setq json (plist-get json :data))) ;; For nbformat v4 support.
(cl-loop
for key in (cond
((functionp ein:output-type-preference)
(funcall ein:output-type-preference json))
(t ein:output-type-preference))
for type = (intern (format ":%s" key)) ; something like `:text'
for value = (plist-get json type) ; FIXME: optimize
when (plist-member json type)
return
(case key
;; NOTE: Normally `javascript' and `html' will not be inserted as
;; they come out after `text'. Maybe it is better to inform user
;; when one of them is inserted.
((javascript text/javascript)
(when dynamic
(ein:log 'info (concat "ein:cell-append-mime-type does not support "
"dynamic javascript. got: %s") value))
(ein:insert-read-only (plist-get json type)))
(emacs-lisp
(when dynamic
(ein:cell-safe-read-eval-insert (plist-get json type))))
((html text/html)
(funcall (ein:output-area-get-html-renderer) (plist-get json type)))
((latex text/latex text text/plain)
(ein:insert-read-only (plist-get json type)))
((svg image/svg+xml)
(ein:insert-image value (ein:fix-mime-type key) t))
((png image/png jpeg image/jpeg)
(ein:insert-image (base64-decode-string value) (ein:fix-mime-type key) t)))))
(defun ein:cell-append-text (data &rest properties) (defun ein:cell-append-text (data &rest properties)
;; escape ANSI in plaintext: ;; escape ANSI in plaintext:
@ -1154,7 +1126,6 @@ prettified text thus be used instead of HTML type."
(when (cl-typep cell 'ein:basecell) (when (cl-typep cell 'ein:basecell)
cell)))) cell))))
;;; Kernel related calls. ;;; Kernel related calls.
(cl-defmethod ein:cell-set-kernel ((cell ein:codecell) kernel) (cl-defmethod ein:cell-set-kernel ((cell ein:codecell) kernel)
@ -1172,7 +1143,6 @@ prettified text thus be used instead of HTML type."
(ein:cell-running-set cell t) (ein:cell-running-set cell t)
(ein:cell-clear-output cell t t t) (ein:cell-clear-output cell t t t)
(ein:cell-set-input-prompt cell "*") (ein:cell-set-input-prompt cell "*")
(setf (slot-value cell 'dynamic) t)
(apply #'ein:kernel-execute kernel code (ein:cell-make-callbacks cell) args)) (apply #'ein:kernel-execute kernel code (ein:cell-make-callbacks cell) args))
(cl-defmethod ein:cell-make-callbacks ((cell ein:codecell)) (cl-defmethod ein:cell-make-callbacks ((cell ein:codecell))
@ -1201,7 +1171,6 @@ prettified text thus be used instead of HTML type."
)) ))
;;; Output area ;;; Output area
;; These function should go to ein-output-area.el. But as cell and ;; These function should go to ein-output-area.el. But as cell and
@ -1220,31 +1189,28 @@ prettified text thus be used instead of HTML type."
(when (or (equal msg-type "pyout") (when (or (equal msg-type "pyout")
(equal msg-type "execute_result")) (equal msg-type "execute_result"))
(plist-put json :prompt_number (plist-get content :execution_count))) (plist-put json :prompt_number (plist-get content :execution_count)))
(setq json (setq json (ein:output-area-convert-mime-types json (plist-get content :data))))
(ein:output-area-convert-mime-types json (plist-get content :data))))
(("pyerr" "error") (("pyerr" "error")
(plist-put json :ename (plist-get content :ename)) (plist-put json :ename (plist-get content :ename))
(plist-put json :evalue (plist-get content :evalue)) (plist-put json :evalue (plist-get content :evalue))
(plist-put json :traceback (plist-get content :traceback)))) (plist-put json :traceback (plist-get content :traceback))))
(ein:cell-append-output cell json t) (ein:cell-append-output cell json)
;; (setf (slot-value cell 'dirty) t) ;; (setf (slot-value cell 'dirty) t)
(ein:events-trigger (slot-value cell 'events) 'maybe_reset_undo.Worksheet cell))) (ein:events-trigger (slot-value cell 'events) 'maybe_reset_undo.Worksheet cell)))
(defun ein:output-area-convert-mime-types (json data) (defun ein:output-area-convert-mime-types (json data)
(cl-loop for (prop . mime) in '((:text . :text/plain) (let ((known-mimes (cl-remove-if-not
(:html . :text/html) #'identity
(:svg . :image/svg+xml) (mapcar (lambda (x) (intern-soft (concat ":" x)))
(:png . :image/png) (mailcap-mime-types)))))
(:jpeg . :image/jpeg) (or (seq-some (lambda (x)
(:latex . :text/latex) (-when-let* ((mime-val
(:json . :application/json) (plist-get data x))
(:javascript . :application/javascript) (minor-kw
(:emacs-lisp . :application/emacs-lisp)) (ein:cell-output-type x)))
when (plist-member data mime) (plist-put json minor-kw mime-val)))
do (plist-put json prop (plist-get data mime))) known-mimes)
json) json)))
(cl-defmethod ein:cell--handle-clear-output ((cell ein:codecell) content (cl-defmethod ein:cell--handle-clear-output ((cell ein:codecell) content
_metadata) _metadata)
@ -1256,7 +1222,6 @@ prettified text thus be used instead of HTML type."
) )
(ein:events-trigger (slot-value cell 'events) 'maybe_reset_undo.Worksheet cell)) (ein:events-trigger (slot-value cell 'events) 'maybe_reset_undo.Worksheet cell))
;;; Misc. ;;; Misc.
(cl-defmethod ein:cell-has-image-ouput-p ((cell ein:codecell)) (cl-defmethod ein:cell-has-image-ouput-p ((cell ein:codecell))

View file

@ -270,17 +270,6 @@ Typed `:input-prompt-number' becomes a problem when reading a
notebook that saved "*". So don't add `:type'!") notebook that saved "*". So don't add `:type'!")
(collapsed :initarg :collapsed :initform nil :type boolean) (collapsed :initarg :collapsed :initform nil :type boolean)
(running :initarg :running :initform nil :type boolean) (running :initarg :running :initform nil :type boolean)
(dynamic :initarg :dynamic :initform nil :type boolean
:documentation "\
Whether cell output is evaluated dynamically or not.
Only Emacs lisp type output data will be affected by this
slot (Javascript will not be evaluated). This value must be set
to `t' when executing cell. See `ein:notebook-execute-cell'.
In the implantation of IPython web client it is passed around via
argument, but since it is difficult to pass argument to EWOC
pretty printer, `ein:codecell' instance holds this setting in a
slot.")
(autoexec :initarg :autoexec :initform nil :type boolean (autoexec :initarg :autoexec :initform nil :type boolean
:documentation "Auto-execution flag. :documentation "Auto-execution flag.

View file

@ -100,13 +100,14 @@ Same as `ein:connect-run-command'."
(const :tag "Ask" ask)) (const :tag "Ask" ask))
:group 'ein) :group 'ein)
(defcustom ein:connect-aotoexec-lighter nil (defcustom ein:connect-autoexec-lighter nil
"String appended to the lighter of `ein:connect-mode' (`ein:c') "String appended to the lighter of `ein:connect-mode' (`ein:c')
when auto-execution mode is on. When `nil', use the same string when auto-execution mode is on. When `nil', use the same string
as `ein:cell-autoexec-prompt'." as `ein:cell-autoexec-prompt'."
:type '(choice (string :tag "String appended to ein:c" "@") :type '(choice (string :tag "String appended to ein:c" "@")
(const :tag "Use `ein:cell-autoexec-prompt'." nil)) (const :tag "Use `ein:cell-autoexec-prompt'." nil))
:group 'ein) :group 'ein)
(define-obsolete-variable-alias 'ein:connect-aotoexec-lighter 'ein:connect-autoexec-lighter "0.17.0")
(defcustom ein:connect-default-notebook nil (defcustom ein:connect-default-notebook nil
"Notebook to be connect when `ein:connect-to-default-notebook' is called. "Notebook to be connect when `ein:connect-to-default-notebook' is called.
@ -383,7 +384,7 @@ notebook."
(defun ein:connect-mode-get-lighter () (defun ein:connect-mode-get-lighter ()
(if (slot-value ein:%connect% 'autoexec) (if (slot-value ein:%connect% 'autoexec)
(format " ein:c%s" (or ein:connect-aotoexec-lighter (format " ein:c%s" (or ein:connect-autoexec-lighter
ein:cell-autoexec-prompt)) ein:cell-autoexec-prompt))
" ein:c")) " ein:c"))

View file

@ -64,16 +64,11 @@ when REPLACE-P returns non-`nil'."
(setcdr attr-cell (funcall replacer val)) (setcdr attr-cell (funcall replacer val))
t)))) t))))
;;; HTML renderer
(defun ein:output-area-get-html-renderer () (defun ein:output-area-get-html-renderer ()
;; FIXME: make this configurable (if (and (fboundp 'shr-insert-document) (fboundp 'libxml-parse-xml-region))
(cond #'ein:insert-html-shr
((and (fboundp 'shr-insert-document) #'ein:insert-read-only))
(fboundp 'libxml-parse-xml-region))
#'ein:insert-html-shr)
(t #'ein:insert-read-only)))
(defcustom ein:shr-env (defcustom ein:shr-env
'((shr-table-horizontal-line ?-) '((shr-table-horizontal-line ?-)
@ -125,6 +120,12 @@ Usage::
(ein:xml-replace-attributes dom 'a 'href replace-p replacer) (ein:xml-replace-attributes dom 'a 'href replace-p replacer)
(ein:xml-replace-attributes dom 'img 'src replace-p replacer))) (ein:xml-replace-attributes dom 'img 'src replace-p replacer)))
(defmacro ein:output-area-case-type (json &rest case-body)
`(progn (aif (plist-get ,json :data) (setq ,json it)) ;; nbformat v4 ???
(seq-some (lambda (type)
(when-let ((value (plist-get ,json type)))
,@case-body))
(list :svg :png :jpeg :text :html :latex :javascript))))
(provide 'ein-output-area) (provide 'ein-output-area)

View file

@ -58,7 +58,8 @@
(autoload 'ein:shared-output-get-cell "ein-shared-output") (autoload 'ein:shared-output-get-cell "ein-shared-output")
(autoload 'ein:shared-output-eval-string "ein-shared-output") (autoload 'ein:shared-output-eval-string "ein-shared-output")
(autoload 'ein:kernel-live-p "ein-kernel") (autoload 'ein:kernel-live-p "ein-kernel")
(autoload 'ein:query-singleton-ajax "ein:query") (autoload 'ein:query-singleton-ajax "ein-query")
(autoload 'ein:output-area-case-type "ein-output-area")
(defvar *ob-ein-sentinel* "[....]" (defvar *ob-ein-sentinel* "[....]"
"Placeholder string replaced after async cell execution") "Placeholder string replaced after async cell execution")
@ -117,22 +118,14 @@
(base64-decode-region (point-min) (point-max))))) (base64-decode-region (point-min) (point-max)))))
(defun ob-ein--return-mime-type (json file) (defun ob-ein--return-mime-type (json file)
(cl-loop (ein:output-area-case-type
for key in ein:output-types-text-preferred json
for type = (intern (format ":%s" key)) ; something like `:text' (cl-case type
for value = (plist-get json type) ; FIXME: optimize ((:svg :png :jpeg)
when (plist-member json type) (ob-ein--write-base64-image value
return (or file (ob-ein--inline-image-info value)))
(case key (format "[[file:%s]]" file))
((svg image/svg) (otherwise value))))
(let ((file (or file (ob-ein--inline-image-info value))))
(ob-ein--write-base64-image value file)
(format "[[file:%s]]" file)))
((png image/png jpeg image/jpeg)
(let ((file (or file (ob-ein--inline-image-info value))))
(ob-ein--write-base64-image value file)
(format "[[file:%s]]" file)))
(t (plist-get json type)))))
(defun ob-ein--process-outputs (outputs params) (defun ob-ein--process-outputs (outputs params)
(let ((file (cdr (assoc :image params)))) (let ((file (cdr (assoc :image params))))

View file

@ -6,7 +6,6 @@
(require 'ein-notebook) (require 'ein-notebook)
(require 'ein-testing-notebook) (require 'ein-testing-notebook)
;; ein:cell-location ;; ein:cell-location
(ert-deftest ein:cell-location-codecell-prompt-beg () (ert-deftest ein:cell-location-codecell-prompt-beg ()
@ -34,7 +33,6 @@
(should (equal (marker-position (ein:cell-location cell :input t)) (should (equal (marker-position (ein:cell-location cell :input t))
(1+ (point)))))) (1+ (point))))))
;; from-json ;; from-json
(ert-deftest eintest:cell-input-prompt-number () (ert-deftest eintest:cell-input-prompt-number ()
@ -78,27 +76,23 @@ In \\[ \\]:
some input some input
")))) "))))
;; Insert pyout/display_data ;; Insert pyout/display_data
(defun eintest:cell-insert-output (outputs regexp) (defun eintest:cell-insert-output (outputs regexp)
(let ((ein:output-type-preference (reverse (if (functionp ein:output-type-preference) (ein:testing-with-one-cell
(funcall ein:output-type-preference nil) (ein:cell-from-json
ein:output-type-preference)))) (list :cell_type "code"
(ein:testing-with-one-cell :outputs outputs
(ein:cell-from-json :source "some input"
(list :cell_type "code" :metadata (list :collapsed json-false :autoscroll json-false)
:outputs outputs :execution_count 111)
:source "some input" :ewoc (oref ein:%worksheet% :ewoc))
:metadata (list :collapsed json-false :autoscroll json-false) (goto-char (ein:cell-location cell))
:execution_count 111) (message "%s" (buffer-string))
:ewoc (oref ein:%worksheet% :ewoc)) (should (looking-at (format "\
(goto-char (ein:cell-location cell))
;; (message "%s" (buffer-string))
(should (looking-at (format "\
In \\[111\\]: In \\[111\\]:
some input some input
%s" regexp)))))) %s" regexp)))))
(defmacro eintest:gene-test-cell-insert-output-pyout-and-display-data (defmacro eintest:gene-test-cell-insert-output-pyout-and-display-data
(name regexps outputs) (name regexps outputs)
@ -109,11 +103,11 @@ some input
(intern (format "ein:cell-insert-output-display-data-%s" name))) (intern (format "ein:cell-insert-output-display-data-%s" name)))
(outputs-pyout (outputs-pyout
(cl-loop for i from 1 (cl-loop for i from 1
for x in outputs for x in outputs
collect collect
;; ein:cell--handle-output doesn't get called ;; ein:cell--handle-output doesn't get called
;; so can't use :execution_count here although that is preferable ;; so can't use :execution_count here although that is preferable
(append x (list :output_type "execute_result" :prompt_number i :metadata nil)))) (append x (list :output_type "execute_result" :prompt_number i :metadata nil))))
(outputs-display-data (outputs-display-data
(mapcar (lambda (x) (append '(:output_type "display_data" :metadata nil) x)) (mapcar (lambda (x) (append '(:output_type "display_data" :metadata nil) x))
outputs)) outputs))
@ -134,47 +128,47 @@ some input
,regexp-display-data))))) ,regexp-display-data)))))
(eintest:gene-test-cell-insert-output-pyout-and-display-data (eintest:gene-test-cell-insert-output-pyout-and-display-data
text ("some output") ((:data (:text/plain "some output")))) text ("some output") ((:data (:text "some output"))))
(eintest:gene-test-cell-insert-output-pyout-and-display-data (eintest:gene-test-cell-insert-output-pyout-and-display-data
latex latex
("some output \\\\LaTeX") ("some output \\\\LaTeX")
((:data (:text/latex "some output \\LaTeX")))) ((:data (:latex "some output \\LaTeX"))))
(when (image-type-available-p 'svg) (when (image-type-available-p 'svg)
(eintest:gene-test-cell-insert-output-pyout-and-display-data (eintest:gene-test-cell-insert-output-pyout-and-display-data
svg svg
("some output text") ("some output text")
((:data (:text/plain "some output text" :image/svg ein:testing-example-svg))))) ((:data (:text "some output text" :svg ein:testing-example-svg)))))
(eintest:gene-test-cell-insert-output-pyout-and-display-data (eintest:gene-test-cell-insert-output-pyout-and-display-data
html html
("some output text") ("some output text")
((:data (:text/plain "some output text" :text/html "<b>not shown</b>")))) ((:data (:text "some output text" :html "<b>not shown</b>"))))
(eintest:gene-test-cell-insert-output-pyout-and-display-data (eintest:gene-test-cell-insert-output-pyout-and-display-data
javascript javascript
("some output text") ("some output text")
((:data (:text/plain "some output text" :text/javascript "$.do.something()")))) ((:data (:text "some output text" :javascript "$.do.something()"))))
(eintest:gene-test-cell-insert-output-pyout-and-display-data (eintest:gene-test-cell-insert-output-pyout-and-display-data
text-two text-two
("first output text" "second output text") ("first output text" "second output text")
((:data (:text/plain "first output text")) (:data (:text/plain "second output text")))) ((:data (:text "first output text")) (:data (:text "second output text"))))
(eintest:gene-test-cell-insert-output-pyout-and-display-data (eintest:gene-test-cell-insert-output-pyout-and-display-data
text-javascript text-javascript
("first output text" "second output text") ("first output text" "second output text")
((:data (:text/plain "first output text")) ((:data (:text "first output text"))
(:data (:text/plain "second output text" :text/javascript "$.do.something()")))) (:data (:text "second output text" :javascript "$.do.something()"))))
(when (image-type-available-p 'svg) (when (image-type-available-p 'svg)
(eintest:gene-test-cell-insert-output-pyout-and-display-data (eintest:gene-test-cell-insert-output-pyout-and-display-data
text-latex-svg text-latex-svg
("first output text" "second output \\\\LaTeX" "some output text") ("first output text" "second output \\\\LaTeX" "some output text")
((:data (:text/plain "first output text")) ((:data (:text "first output text"))
(:data (:text/latex "second output \\LaTeX")) (:data (:latex "second output \\LaTeX"))
(:data (:text/plain "some output text" :image/svg ein:testing-example-svg))))) (:data (:text "some output text" :svg ein:testing-example-svg)))))
;; Insert pyerr ;; Insert pyerr

View file

@ -16,11 +16,9 @@ if [ "x$UNAME" = "xLinux" ] ; then
make && make install make && make install
find ${WORKDIR}/R -name R -print find ${WORKDIR}/R -name R -print
fi fi
R -e "install.packages('IRkernel', repos='http://cran.mirrors.hoobly.com')"
R -e "IRkernel::installspec()"
elif [ "x$UNAME" = "xDarwin" ]; then elif [ "x$UNAME" = "xDarwin" ]; then
brew list r &>/dev/null || HOMEBREW_NO_AUTO_UPDATE=1 brew install r brew list r &>/dev/null || HOMEBREW_NO_AUTO_UPDATE=1 brew install r
R -e "install.packages('IRkernel', repos='http://cran.mirrors.hoobly.com')"
R -e "IRkernel::installspec()"
fi fi
R -e "install.packages('IRkernel', repos='http://cran.mirrors.hoobly.com')"
R -e "IRkernel::installspec()"
R --version R --version