3
$\begingroup$

I am trying to figure out a way to change the contents of a cell that has previously been evaluated in my notebook. To do this, I'd like to overwrite the cell.

I've seen questions like How to pipe a stream to another notebook? and How do I direct output to a specific notebook or cell? and so far they have not helped me accomplish this.

NotebookApply[cell, data] 

The above is supposed to write data to the specified cell, but I haven't had any luck with this, I'm most likely incorrectly identifying the cell.

The most promising example I've seen so far has been this from the CellObject page:

  Do[CellPrint[
   Cell["1", "Output", ShowCellTags -> True, 
    CellTags -> "overwrite" <> ToString[i]]], {i, 1, 3}];
   obj = Cells[CellTags -> "overwrite2"][[1]];
  NotebookWrite[obj, Cell["2", "Output"]];

But I don't really understand what it's doing, and I don't understand how to adapt it to suit my needs.

If I have thisCell identifying the CellObject I'd like to change...

NotebookWrite[InputNotebook[], 
 thisCell  = Cell[BoxData[RowBox[{"mysteryVar = 0"}]], "Input"]]

How can I overwrite the contents of this cell? (I'm running ver 9). Thanks!

$\endgroup$
  • $\begingroup$ Could you describe step by step what do you need? Which cell has to be overwritten? The whole cell or only a contents, meaning that options are preserved. How do you want to find this cell, through CellTags? etc etc. $\endgroup$ – Kuba Jul 1 '14 at 13:09
  • $\begingroup$ I'd be happy to find this cell any way, through cell tags or any other method. I only want the contents of the cell overwritten. The idea is that I'd be able to evaluate the cell, then go on and do other things, then further down in the notebook I'd have code to overwrite the contents of the thisCell, previously evaluated in the notebook. So if I saved it and evaluated again, the new contents of thisCell would run. $\endgroup$ – user15921 Jul 1 '14 at 13:12
4
$\begingroup$

Too long for a comment, please tell me if this is what you need.

Evaluate it in a cell you want:

SetOptions[EvaluationCell[], CellTags -> "target"]

and then later you can do:

NotebookWrite[
 Cells[CellTags -> "target"][[ 1]],
 Cell[BoxData[RowBox[{"mysteryVar = 0"}]], "Input", CellTags -> "target"]
 ]

so that first cell was replaced. I've added the CellTags again so you can repeat it.

$\endgroup$
  • $\begingroup$ This works for me! Thank you so much! $\endgroup$ – user15921 Jul 1 '14 at 13:24
3
$\begingroup$

It took me a while to figure this stuff out as well. First, it's important to understand the difference between a Cell expression and a CellObject.

A Cell

is the low-level representation of a cell inside a Mathematica notebook.

So basically it's just an expression wrapped with Cell, and in that sense it is no different than any other expression.

A CellObject

is an object that represents a cell in an open notebook in the front end.

The only way you get can get a CellObject is if the system returns it to you; you can't write out an expression that references an existing cell without obtaining the ID from the kernel.

So thisCell does not in fact identify a CellObject, but rather is just a boring Cell expression.

thisCell

Cell[BoxData[RowBox[{"mysteryVar = 0"}]], "Input"]

Because thisCell is just an expression, there is nothing unique about it:

Do[
  NotebookWrite[EvaluationNotebook[], thisCell],
  {3}]

mysteryVar = 0

mysteryVar = 0

mysteryVar = 0

So you need to get your hands on a CellObject, which means you need to use a function provided by Mathematica.

Here's an example:

NotebookWrite[
  InputNotebook[], 
  cellExpression = Cell[BoxData[RowBox[{"mysteryVar = 0"}]], "Input"]];
cellBefore = EvaluationCell[];

cellBefore is a CellObject referring to the cell containing this code. Evaluating this cell also wrote another cell after it:

mysteryVar = 0

We need to get there via SelectionMove. Here's one way:

SelectionMove[cellBefore, Next, Cell]

This means select the cell after cellBefore. Now we can overwrite that selection:

NotebookWrite[
 EvaluationNotebook[],
 cellExpression /. s_String :> StringReplace[s, "0" -> "17"]]

mysteryVar = 17

But as pointed out by Kuba, it's often easier to tag a cell if you need to access it later. The method I've described here requires you to keep track of what's where, etc.

$\endgroup$
  • 1
    $\begingroup$ Thank you so much for all this information! I was quite confused about the cell/CellObject distinction, you've made the distinction easier to understand. $\endgroup$ – user15921 Jul 1 '14 at 13:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.