I would like to make Mathematica documents with hidden calculations, such that they can be visualized on demand. In general it can be done in several forms and I actually use some. I would like to ask about one specific way of doing that. Namely, I would like to make a button incorporated into either inline or input cell. Upon pressing on this button a separate notebook should open containing the calculations.

It is easy to make this, if the document only contains output cells. For instance, this

button1[expr_, sz_] := Button["Evaluate expression",
   CreateDocument[expr, WindowSize -> {sz, sz}]];

button1[Expand[(x + y)^2], 300]

makes a button which opens the window with the result x^2+2xy+y^2.

It is easy to make a notebook with a cell that can be later evaluated:

button2[expr_, sz_] := Button["Evaluate expression",
    ExpressionCell[expr, "Input"],
    WindowSize -> {sz, sz}]];
button2[Expand[(x + y)^2], 300]

but it also returns the already evaluated result. For whatever reason this:

SetAttributes[button2, HoldFirst];

does not help.

One can also show the both unevaluated input and the output like this:

button3[expr_, sz_: 300] :=
  Button["Show expression",
   nb = CreateDocument[
       {ExpressionCell[Unevaluated[expr], "Input"], 
      ExpressionCell[Button["Evaluate", Print@Evaluate[expr]], 
       "Input" ]},
     WindowSize -> {sz, sz}
button3[Expand[(x + y)^2]]

However, I would like to get rid of the operator Unevaluated in the first cell.

My aim is to get a separate notebook that is generated from the initial document. This notebook should have an input and the corresponding output cell (or cells), which a) shows how some result has been achieved in the past and what was this result and b) in which I could try to change something in the input cell(s) and see what would happen, while the source code lays somewhere unchanged. Thank you, Alexei


With minor modification of your code, you can use

   button3[expr_, sz_: 300] := 
   Button["Show expression", 
   nb = CreateDocument[{ExpressionCell[expr, "Input"], 
    CellPrint@ExpressionCell[expr /. Defer[x_] :> x, "Output"]], 
   "Input"]}, WindowSize -> {sz, sz}]];
   button3[Defer@Expand[(x + y)^2]]


   button3[expr_, sz_: 300] := 
   Button["Show expression", 
   nb = CreateDocument[{ExpressionCell[expr, "Input"], 
    CellPrint@ExpressionCell[ReleaseHold@expr, "Output"]], 
   "Input"]}, WindowSize -> {sz, sz}]];
   button3[HoldForm@Expand[(x + y)^2]]

EDIT: I would go with Heike's s solution. But the following maybe of pedagocial value: ClearAll[func] preceeding definitions of functions that you edit/re-edit until you find a working version is a good practice. Forgetting this is the reason for the convoluted workaround in my original answer. So, the following works as OP intended:

   SetAttributes[button4, HoldFirst]; 
   button4[expr_, sz_: 300] := 
   Button["Show expression", 
   nb = CreateDocument[{ExpressionCell[Defer@expr, "Input"], 
   ExpressionCell[Button["Close window", NotebookClose[nb]]]}, 
   WindowSize -> {sz, sz}]]; 
   button4[Expand[(x + y)^2]]
  • $\begingroup$ Thank you. In principle, my Evaluate button is somewhat misleading. I used it, since could not see a better way to separate the input and output. The minimalistic code that fits my needs is the version of the first of the above possibilities: $\endgroup$ May 3 '12 at 14:11
  • $\begingroup$ which is button4[expr_, sz_: 300] := Button["Show expression", nb = CreateDocument[{ExpressionCell[expr, "Input"], ExpressionCell[Evaluate[expr /. Defer[x_] :> x], "Output"], ExpressionCell[Button["Close window", NotebookClose[nb]]] }, WindowSize -> {sz, sz}] ]; button4[Defer@Expand[(x + y)^2]] $\endgroup$ May 3 '12 at 14:12
  • $\begingroup$ I cannot understand, however, why one needs to use Defer as it is used in your code, rather than placing it inside the function like follows: ... ExpressionCell[Defer@expr, "Input"] ...? I tried and it does not work. Can you explain, why? $\endgroup$ May 3 '12 at 14:17
  • $\begingroup$ @AlexeiBoulbitch, actually that's what I tried first for both Defer and HoldForm. I, too, find it puzzling that both ExpressionCell[HoldForm[expr]] and ExpressionCell[Defer[expr]] evaluate when they are inside CreateDocument. $\endgroup$
    – kglr
    May 3 '12 at 17:00
  • $\begingroup$ But does not when both the attribute HoldFirst and defer are applied. I did not notice any trace of such a strategy in documentation. Good to know. Thank you. I also like the Heike's solution. It works beautifully. However, for a massive use I prefer a simple code that I fully understand and can change, if necessary. $\endgroup$ May 4 '12 at 8:52

Not sure if this is what you had in mind, but maybe you could do something like this

SetAttributes[button, HoldFirst];
button[expr_, sz_: 300] := 
  Button["Show expression", 
   nb = CreateDocument[{ExpressionCell[Defer[expr], "Input", 
       CellTags -> "input"], ExpressionCell[Button["Evaluate",
         cell = NotebookRead[ButtonNotebook[]];
         SelectionMove[ButtonNotebook[], After, Notebook];
         CellPrint[Cell[cell[[1]], "Input", Editable -> False]];
         CellPrint[ExpressionCell[ToExpression[cell[[1]]], "Output", Editable -> False]]
         ]], "Input"]}, WindowSize -> {sz, sz}]];

button[Expand[(x + y)^2]]

Pressing the Show Expression button will create a popup notebook with the input form of the expression plus an Evaluate button. Every time you press this button the first input cell plus the corresponding output will be copied at the bottom of the notebook. This will allow you to keep track of the changes made to the original expression.


  • $\begingroup$ uhhhh - nice drop shadow ;-) $\endgroup$
    – Yves Klett
    May 3 '12 at 13:09
  • $\begingroup$ @YvesKlett that's the default when taking a screenshot of a window in OS X. $\endgroup$
    – Heike
    May 3 '12 at 13:17
  • $\begingroup$ Coming from the strictly rectangular Windows desktop world, I had that one down as nifty Mathematica-based post-processing... might be worthy eyecandy for the upload palette. $\endgroup$
    – Yves Klett
    May 3 '12 at 13:22
  • $\begingroup$ Thank you, it is nice, but I feel guilty, since I mislead everybody with the use of the evaluate button. I explained it in detail in the comment to the first answer, could you kindly have a look? $\endgroup$ May 3 '12 at 14:17

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.