7

Is it possible in an IPython-Notebook cell to get the previous (above) cell content ?

I can see previous output with %capture magic function but I don't find how to get the previous cell content.

jootl
  • 699
  • 2
  • 8
  • 16

3 Answers3

2
%recall jupyter_notebook_cell_number

Should give you the code that was last executed in indicated particular notebook cell, jupyter_notebook_cell_number

meljw
  • 21
  • 4
1

I didn't find how to get the previous content cell in a cell.

But I found another solution, creating a custom magic notebook function to capture the cell content and work with that.

jootl
  • 699
  • 2
  • 8
  • 16
  • Advice on how to go about creating the fuction? – scharfmn Aug 28 '15 at 17:52
  • Sorry for the late... I created a "magic" Notebook class with `@magics_class` annotation and with it, you can define a function with `@cell_magic` annotation. The function has the following prototype `def my_function(self, line, cell)` and you can work with `cell` parameter. – jootl Jan 15 '16 at 13:28
  • To further this: https://ipython.readthedocs.io/en/stable/config/custommagics.html – Matteo Ferla Apr 29 '20 at 12:38
1

The documentation for the input catching system is rather informative. The returned output (not cell output content) is stored in _oh dictionary and the returned output is added to the page within the .output_area DOM element as a div element with the classes .output_subarea, .output_text and uniquely .output_result. Printed or displayed (IPython.display.display also have the first two classes and print in particular has .output_stream .output_stdout.

_oh is a dictionary and the integer is the same as that you can see on the left of the input (.input_prompt div).

In other words the cell content is rather formatted as expected. And you can in fact add your own HTML.

from IPython.display import display, HTML
display(HTML('<h1>HELLO WORLD</h1>'))
display(HTML(<script>alert("hello world");</script>'))

This shows you can add JS within a Python cells —but this has a big flaw. Likewise, in JS you can execute python code.

IPython.notebook.kernel.execute("python_variable="+JSON.stringify(jsVariable));

However, a JS IPython call is executed when the kernel is idle. Therefore you have to wait for the cell to finish before accessing python_variable. So there's no point doing it all in one cell and regular cell magic works.

Consequently, the following JS magic will give a output dictionary whose keys are cell numbers and values are the content. As mentioned the cell content is formatted, so if you want to change the following based on the class of the element in the cell you can refer to the aforementioned CSS classes.

// querySelectorAll returns a NodeList which lacks most Array functions
// so destructuring into array
const outputs=[...document.querySelectorAll(".cell")].map(
        cell=> {
            const RawCellN=cell.querySelector(".input_prompt").innerText;
            // \xa0 is star. current: skip.
            if (RawCellN.match(/\[(\d+)\]/) === null) return null; 
            const cellN =  parseInt(RawCellN.match(/\[(\d+)\]/)[1]);
            const outputs= [...cell.querySelectorAll(".output_subarea")].map(
                subarea => subarea.innerText.trim());
            return [cellN, outputs.filter(out => out.length !== 0)];
        }
    ).filter(value => value !== null); // star cell was skipped.

// pass on the data to python
IPython.notebook.kernel.execute("outputs=dict("+JSON.stringify(outputs)+")")
Matteo Ferla
  • 2,128
  • 1
  • 16
  • 27