Add worksheet tags to nbformat 4 notebooks

NBformat 4 has a tag key in the cell metadata. We use it to tag a cell
depending on which worksheet it is in. For now the code does nothing
else with this tag, but the goal is to reimplement multiple worksheets
in ein.
This commit is contained in:
John Miller 2015-05-14 09:39:47 -05:00
parent d2681d88e3
commit 5886498684
5 changed files with 127 additions and 46 deletions

View file

@ -3,7 +3,10 @@
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
"collapsed": true,
"tags": [
"worksheet-0"
]
},
"source": [
"# Adding Imenu Support"
@ -12,7 +15,10 @@
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
"collapsed": true,
"tags": [
"worksheet-0"
]
},
"source": [
"## Subheader"
@ -21,7 +27,10 @@
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
"collapsed": true,
"tags": [
"worksheet-0"
]
},
"source": [
"Seems to be a couple ways of doing this:\n",
@ -35,7 +44,10 @@
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
"collapsed": false,
"tags": [
"worksheet-0"
]
},
"outputs": [],
"source": [
@ -55,7 +67,10 @@
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
"collapsed": true,
"tags": [
"worksheet-0"
]
},
"source": [
"# Another Header"
@ -63,9 +78,12 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {
"collapsed": false
"collapsed": false,
"tags": [
"worksheet-0"
]
},
"outputs": [
{
@ -75,7 +93,7 @@
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-3-05c9758a9c21>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;36m1\u001b[0m\u001b[1;33m/\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;32m<ipython-input-4-05c9758a9c21>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;36m1\u001b[0m\u001b[1;33m/\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;31mZeroDivisionError\u001b[0m: division by zero"
]
}
@ -84,11 +102,68 @@
"1/0"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false,
"tags": [
"worksheet-0"
]
},
"outputs": [],
"source": [
"import inspect"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
"collapsed": false,
"tags": [
"worksheet-0"
]
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"tags": [
"worksheet-1"
]
},
"outputs": [],
"source": [
"1+1"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"tags": [
"worksheet-1"
]
},
"outputs": [],
"source": [
"inspect"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"tags": [
"worksheet-1"
]
},
"outputs": [],
"source": []

View file

@ -3,6 +3,13 @@
* Overview
* Design
** Notebook Buffer
Notebook information is stored as a [[file:lisp/ein-notebook.el::ein:$notebook][struct]]. Always associated with a buffer,
[[file:lisp/ein-notebook.el::ein:notebook-buffer][ein:notebook-buffer]] is used to find buffer associated with a notebook.
Notebook does not hold cells, that is delegated to instances of the [[file:lisp/ein-worksheet.el::ein:worksheet][worksheet]]
class. Instances are stored as a list in the `ein:$notebook-worksheets` slot.
** Notebooklist Buffer
** Kernel communication
** Contents API
@ -65,3 +72,20 @@ What needs to be done:
~input-prompt-number~.
4. Call ~ein:cell-goto~ on that cell. May need to swap buffers first.
** Return of worksheets
tkf/ein and IPython 2.x allowed for multiple worksheets within an individual
notebook. This feature was removed in 3.0 since multiple worksheets do not make
much sense in the context of a tabbed web browser interface. EIN's legacy code
still supports worksheets, though at the moment that information is lost upon
saving a notebook.
Having multiple worksheet support makes some sense for ein; below is thinking on
how to reimplement this feature.
IPython nbformat 4 specifies a [[http://ipython.org/ipython-doc/3/notebook/nbformat.html#metadata][metadata]] key which can be used to store general
information. Cell metadad has a tag key which is a "A list of string tags on the
cell. Commas are not allowed in a tag."
Best place to set the tag key is when generating [[content]] for saving a notebook.

View file

@ -1001,8 +1001,9 @@ prettified text thus be used instead of HTML type."
(defun ein:output-property-p (maybe-property)
(assoc maybe-property ein:output-type-map))
(defmethod ein:cell-to-nb4-json ((cell ein:codecell) &optional discard-output)
(let ((metadata `((collapsed . ,(if (oref cell :collapsed) t json-false))))
(defmethod ein:cell-to-nb4-json ((cell ein:codecell) wsidx &optional discard-output)
(let ((metadata `((collapsed . ,(if (oref cell :collapsed) t json-false))
(tags . ((format "worksheet-%s" wsidx)))))
(outputs (if discard-output []
(oref cell :outputs)))
(renamed-outputs '())
@ -1068,16 +1069,18 @@ prettified text thus be used instead of HTML type."
`((cell_type . ,(oref cell :cell-type))
(source . ,(ein:cell-get-text cell))))
(defmethod ein:cell-to-nb4-json ((cell ein:textcell) &optional discard-output)
(defmethod ein:cell-to-nb4-json ((cell ein:textcell) wsidx &optional discard-output)
`((cell_type . ,(oref cell :cell-type))
(source . ,(ein:cell-get-text cell))
(metadata . ((collapsed . t)))))
(metadata . ((collapsed . t)
(tags . (,(format "worksheet-%s" wsidx)))))))
(defmethod ein:cell-to-nb4-json ((cell ein:headingcell) &optional discard-output)
(defmethod ein:cell-to-nb4-json ((cell ein:headingcell) wsidx &optional discard-output)
(let ((header (make-string (oref cell :level) ?#)))
`((cell_type . "markdown")
(source . ,(format "%s %s" header (ein:cell-get-text cell)))
(metadata . ((collapsed . t))))))
(metadata . ((collapsed . t)
(tags . (,(format "worksheet-%s" wsidx))))))))
(defmethod ein:cell-to-json ((cell ein:headingcell) &optional discard-output)
(let ((json (call-next-method)))

View file

@ -636,8 +636,13 @@ of NOTEBOOK."
(defun ein:write-nbformat4-worksheets (notebook)
(ein:log 'info "Writing notebook %s as nbformat 4." (ein:$notebook-notebook-name notebook))
(let ((all-cells (first (mapcar #'ein:worksheet-to-nb4-json
(ein:$notebook-worksheets notebook)))))
(let ((all-cells
(loop for ws in (ein:$notebook-worksheets notebook)
for i from 0
append (ein:worksheet-to-nb4-json ws i))
;; (mapcar #'ein:worksheet-to-nb4-json
;; (ein:$notebook-worksheets notebook))
))
`((metadata . ,(ein:aif (ein:$notebook-metadata notebook)
it
(make-hash-table)))
@ -649,33 +654,7 @@ of NOTEBOOK."
'notebook_saving.Notebook)
(ein:content-save content
#'ein:notebook-save-notebook-success
(list notebook callback cbargs))
;; (let ((data (ein:content-to-json content)))
;; ;; (push `(path . ,(ein:$notebook-notebook-path notebook)) data)
;; ;; (push `(name . ,(ein:$notebook-notebook-name notebook)) data)
;; ;; (push `(type . "notebook") data)
;; (ein:query-singleton-ajax
;; (list 'notebook-save
;; (ein:$notebook-url-or-port notebook)
;; (ein:$notebook-notebook-path notebook)
;; (ein:$notebook-notebook-name notebook))
;; (ein:notebook-url notebook)
;; :timeout ein:notebook-querty-timeout-save
;; :type "PUT"
;; :headers '(("Content-Type" . "application/json"))
;; :data data
;; :error (apply-partially #'ein:notebook-save-notebook-error notebook)
;; :success (apply-partially #'ein:notebook-save-notebook-workaround
;; notebook retry callback cbarg)
;; :status-code
;; `((200 . ,(apply-partially
;; (lambda (notebook callback cbarg &rest rest)
;; (apply #'ein:notebook-save-notebook-success
;; notebook rest)
;; (when callback
;; (apply callback cbarg rest)))
;; notebook callback cbarg)))))
))
(list notebook callback cbargs))))
(defun ein:notebook-save-notebook-command ()
"Save the notebook."

View file

@ -242,12 +242,12 @@ current buffer."
`((cells . ,(apply #'vector cells))
,@(ein:aand (oref ws :metadata) `((metadata . ,it))))))
(defmethod ein:worksheet-to-nb4-json ((ws ein:worksheet))
(defmethod ein:worksheet-to-nb4-json ((ws ein:worksheet) wsidx)
(let* ((discard-output-p (oref ws :discard-output-p))
(cells (ein:with-possibly-killed-buffer (ein:worksheet-buffer ws)
(mapcar (lambda (c)
(ein:cell-to-nb4-json
c (ein:funcall-packed discard-output-p c)))
c wsidx (ein:funcall-packed discard-output-p c)))
(ein:worksheet-get-cells ws)))))
cells))