mirror of
https://github.com/vale981/emacs-ipython-notebook
synced 2025-03-05 17:11:41 -05:00
confused about pyouts
This commit is contained in:
parent
0ee5f01fe4
commit
9ac1bf62e5
9 changed files with 152 additions and 210 deletions
|
@ -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"
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
;;; -*- lexical-binding: t; -*-
|
||||||
(require 'f)
|
(require 'f)
|
||||||
(require 'espuds)
|
(require 'espuds)
|
||||||
(require 'ert)
|
(require 'ert)
|
||||||
|
|
231
lisp/ein-cell.el
231
lisp/ein-cell.el
|
@ -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))
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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"))
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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))))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue