2
$\begingroup$

Is there a way to create a cell with no form? Usually a cell is either an input cell or an output cell, for example if you do NotebookWrite[InputNotebook, "test"] and hit Ctrl+E, the cell is in the input form Cell["test", "Input"]. However, if you do CreateDocument["test"], there is no form related to the cell, i.e., Cell["test"]. Is there a way to create a cell with no form using NotebookWrite[]?

$\endgroup$
  • 1
    $\begingroup$ Is NotebookWrite[EvaluationNotebook[], Cell["test"]] or CellPrint[Cell["test"]] what you are after? $\endgroup$ – Kuba May 27 '14 at 17:08
  • $\begingroup$ NotebookWrite works in this case, thank you. I am actually trying to manipulate the notebook from a palette, using CellPrint always prints the cell in the message box instead of the InputNotebook[] $\endgroup$ – Yituo May 28 '14 at 13:01
5
$\begingroup$

When you evaluate CreateDocument["test"] you get a new notebook with a single text cell whose content is "test".

I believe you would get the same result with

nb = CreateDocument[];
NotebookWrite[nb, Cell["test"]]

The second argument to NotebookWrite is the "data" you want to write to nb. If you specify that you want a text cell, then that's what you'll get. As the documentation states, if you provide some data that is not a Cell construct, and one is needed, then it will wrap the data in a Cell construct.

|improve this answer|||||
$\endgroup$
  • $\begingroup$ There is a difference between a Cell with no assigned style as the OP wants (for what reason?) and a "Text" cell, which you might make clearer in your answer. You can easily see that with NotebookWrite[nb,Cell["test"]] vs. NotebookWrite[nb,Cell["test","Text"]]. What these two cases look like depends on the active stylesheet, of course... $\endgroup$ – Albert Retey May 27 '14 at 21:55
  • 1
    $\begingroup$ @albert-retey: The difference is the style of the text cell. Both Cell["test"] and Cell["test", "Text"] are text cells, but the latter has a named style. $\endgroup$ – Christopher Cole May 27 '14 at 22:03
  • $\begingroup$ yes, my porposal was that you explain in your answer what exactly it is that you refer to with "text cell". I guess you call a "text cell" one that has a string or TextData as content as opposed to an expression cell which has BoxData as content, which -- as you mentioned -- hasn't anything to do with its style, which can be "Text" or not. It probably also is worth mentioning that some functions (e.g. CellPrint and NotebookWrite) expect low level Cell expression as arguments while others (like CreateDocument) accept higher level stuff like TextCell... $\endgroup$ – Albert Retey May 28 '14 at 8:17
  • $\begingroup$ @AlbertRetey I wanted this because of the alignment issues actually. The cells generated by NotebookWrite[] does not line up with other cells given by CreateDocument[], and when I looked at the cell structure, the only difference is that the cells given by CreateDocument[] does not have a style $\endgroup$ – Yituo May 28 '14 at 13:05
5
$\begingroup$

There are two things that I think need to be distinguished to understand the different behavior of NotebookWrite[InputNotebook[], "test"] and CreateDocument["test"]:

Cell Representation

There are two levels of abstraction for expressions representing cells in Mathematica. The older lower level representation is what NotebookWrite and e.g. the notebook option DockedCells expect exclusively. That are expressions with head Cell which need either a string, a TextData or a BoxData expression as first argument, the style of the cell as second and as many cell-options as you want after that. If you want the cell to show 2d-formatted content, you have to supply the corresponding boxes wrapped in BoxData as the first argument. It seems common to refer to cells which have a string or TextData in the first argument as text cells while cells which have a box-formatted expression wrapped in BoxData are refered to as expression cells.

There is also a newer form of cell-reperesentation, namely TextCell and ExpressionCell and they are very similar to Cell but make explicit what their content is meant to be and do some automatic conversion of the first argument if and when necessary. It might be of interest that if not just given a string as first argument, TextCell still creates an expression cell. Some functions as CellPrint and CreateDocument will accept these in their arguments (as well as the lower level Cell) and at some point they are automatically converted to the corresponding lower level Cell expressions that you see in the frontend when e.g. hitting Ctrl+Shift+E.

Most functions which accept cells in their input do some automatical conversions to cells when they find just strings, and obviously what NotebookWrite does is in that case is different than what CreateDocument does. If you want the two to create the same thing, then you should -- as others have suggested -- explicitly tell them what you want and use a specific cell expression instead of just a string.

Cell Styles

Independent of their content (text cell containing string vs. expression cell containing boxes) there are the cell styles which control how a cell will look and behave. I honestly don't know what exactly the documented behavior is for cells with no style given, so to some extent I think one is asking for some arbitrariness if one creates such cells. The look and behavior of a cell is controlled by the stylesheet of the notebook in which the cell lives. So by explicitly stating which style the cells you generate should be will make them look alike and e.g. their content should be nicely aligned.

But you can overwrite every setting that affects a cell through its style by explicitly setting options for the corresponding cell. That is what happens if you use the Cell or Format menus of the frontend to manipulate a selecte cell but can just as well done programmatically. Making use of that you can create cells which will show their content nicely aligned even if they have different (or no) styles defined, e.g.:

cellmargins = {{10, Inherited}, {Inherited, Inherited}};
nb = CreateDocument[Cell["line 1", "Section", CellMargins -> cellmargins]];
SelectionMove[nb, After, Notebook];
NotebookWrite[nb, Cell["line 2", CellMargins -> cellmargins]];
NotebookWrite[nb, Cell["line 3", "Text", CellMargins -> cellmargins]]

the above does set the left cell margins of all cells to 10, which will overwrite the settings for their corresponding style. Of course you could use the same mechanism to make content of cells with the same style not be aligned. You might have noticed the usage of Inherited for the other alignment values which will leave those at the style-specific settings. You could even do such an alignment a-posteriori once the content of a notebook has been created in any way. The following will enforce larger left margins in the notebook that just has been generated:

SelectionMove[nb, All, Notebook];
SetOptions[NotebookSelection[nb], 
 CellMargins -> {{50, Inherited}, {Inherited, Inherited}}]
|improve this answer|||||
$\endgroup$
  • 1
    $\begingroup$ I think it's worth noting that Paste[…] seems to accomplish the same thing as NotebookWrite[EvaluationNotebook,…], except that Paste can handle the higher-level constructs like EvaluationCell. When I discovered that, it saved me a lot of grief. $\endgroup$ – ibeatty Jul 14 '15 at 21:21

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.