Message Boards Message Boards

Replace Inputs with PasteButton containing the Inputs?

POSTED BY: Seth Chandler
9 Replies

Carl,

That is a clever way to do it!

As the stylesheet is written, the expression is evaluated and the input cell is replaced with a button. When you push the button, the button replaces itself with the original cell.

I would assume (although I have not tried to do this!) that the Stylesheet you propose can be modified slightly to make the button so that when you push the button it actually evaluates the expression on push. Is there any reason that the stylesheet could not use the same button code that I proposed to combine this functionality with the ease of your stylesheet? I wonder if you would you have to change from CellEpilog to CellEvaluationFunction to make this work??

regards

POSTED BY: Neil Singer

You could consider using a style sheet that does this automatically instead of post-processing afterwards. For example:

Notebook[{
    Cell[StyleData[StyleDefinitions -> "Default.nb"]],

    Cell[StyleData["HideInput", StyleDefinitions -> StyleData["Input"]],
        CellEpilog:>With[{obj = EvaluationCell[]}, {cell = NotebookRead[obj]},
            NotebookWrite[
                obj, 
                Cell[
                    BoxData @ ButtonBox[
                        "\"Press me\"",
                        ButtonFunction :> NotebookWrite[EvaluationCell[], cell],
                        Evaluator -> Automatic
                    ],
                    "Input"
                ]
            ]
        ],
        MenuSortingValue->1501
    ]
    },
    FrontEndVersion->"11.0 for Mac OS X x86 (32-bit, 64-bit Kernel) (July 28, 2016)",
    StyleDefinitions->"PrivateStylesheetFormatting.nb"
]

Install the style sheet, and then use the "Hide Input" style. After evaluating the "Hide Input" cell, the CellEpilog replaces the cell with a "Press me" button.

POSTED BY: Carl Woll

Interesting idea. My workflow is likely going to be (1) create the problem set or teaching notebooks and include all of my answers; (2) Cell Tag the inputs and outputs I do not want the students to see with some CellTag like "answer"; (3) Have a separate Mathematica notebook that slurps up the teaching notebook (NotebookGet[NotebookOpen["some file"]]) and creates two new files, a teaching version and a student version. The teaching version will be the original notebook but the Inputs tagged "answer" will be replaced by a Press Me button as folks here have implemented; Outputs tagged "answer" will likely be deleted. The student version will be the original notebook but any cell tagged "answer" will be deleted and, then, any empty CellGroups resulting will themselves be deleted. The teaching version and student version will then be NotebookPut to a private and public directory.

With the help of this group, I think I now have the pieces to make this happen. Any ideas on an improved workflow or other ideas on construction of problem sets appreciated.

POSTED BY: Seth Chandler

Glad to help!

What you are doing is a cool idea for an educational notebook.

By the way, the original button that I made was from this code:

Button[Style["  Print Me  ", 18, Bold, Red], 
 NotebookWrite[EvaluationBox[], Cell["y = x^32", "Input"]], 
 Background -> Lighter[Gray, 0.9]]

By looking at how Mathematica converted this button in a notebook provided the code for the rule posted above. I deleted a few of the options that were clearly not needed but I am not sure if all the of the remaining options are necessary/important.

POSTED BY: Neil Singer

So, here is the inferior solution I came up with:

nb=NotebookOpen["some file"];
NotebookPut[
 NotebookGet[nb] /. 
  Cell[boxes_, "Input", stuff___] :> 
   Cell[BoxData[
     ButtonBox["\<\"press me\"\>", BaseStyle -> "Paste", 
      ButtonData -> boxes]], "Input", stuff]
 ]

The "inferiority" comes not from undue modesty but because your version has the desirable feature of inserting in the right place instead of where the insertion point happens to be at that time. Thanks!

POSTED BY: Seth Chandler

This is what it looks like:

Before applying the posted code:

enter image description here

After running the code: (Note you can optionally delete the output cells if you do not want them there)

enter image description here

After clicking on two of the buttons:

enter image description here

POSTED BY: Neil Singer

Seth,

You were very close!! This will do what you want. I made the button so it replaces itself with the input text. The key is making the button an output cell and have it reference itself with EvaluationBox[] when it does a notebook write so it replaces itself with the input text. This is a variant of something I have done in the past which is to make a termination button that temporarily prints itself and goes away when the calculation is done.

nb=NotebookOpen["some file"];
transformed = NotebookGet[nb] /. 
Cell[boxes_, "Input", stuff___] :> 
  Cell[BoxData[
    ButtonBox[
     StyleBox["\"  Print Me  \"", FontSize -> 18, FontWeight -> Bold, 
      FontColor -> RGBColor[1, 0, 0]], Appearance -> Automatic, 
     Background -> RGBColor[0.95, 0.95, 0.95], 
     ButtonFunction :> 
      NotebookWrite[EvaluationBox[], Cell[boxes, "Input", stuff]], 
     Evaluator -> Automatic, Method -> "Preemptive"]], "Output"];
NotebookPut[transformed]

Regards

POSTED BY: Neil Singer
Posted 7 years ago

Seth,

You were very close!! This will do what you want. I made the button so it replaces itself with the input text. The key is making the button an output cell and have it reference itself with EvaluationBox[] when it does a notebook write so it replaces itself with the input text. This is a variant of something I have done in the past which is to make a termination button that temporarily prints itself and goes away when the calculation is done.

nb=NotebookOpen["some file"];
transformed = NotebookGet[nb] /. 
Cell[boxes_, "Input", stuff___] :> 
  Cell[BoxData[
    ButtonBox[
     StyleBox["\"  Print Me  \"", FontSize -> 18, FontWeight -> Bold, 
      FontColor -> RGBColor[1, 0, 0]], Appearance -> Automatic, 
     Background -> RGBColor[0.95, 0.95, 0.95], 
     ButtonFunction :> 
      NotebookWrite[EvaluationBox[], Cell[boxes, "Input", stuff]], 
     Evaluator -> Automatic, Method -> "Preemptive"]], "Output"];
NotebookPut[transformed]

Regards

POSTED BY: Updating Name

One thing to try is to place your proposed Cell into a front end, and see if it works. In your case, when I try to do this using your template, I get:

CellPrint@Cell[ButtonBox["Press me",BaseStyle->Paste,ButtonData->Defer[ToExpression["1"]]],"Input"]

(* BoxData["Press me", BaseStyle -> Paste, ButtonData -> Defer[ToExpression["1"]]] *)

And you can see why you're getting your BoxData error message. I suggest you try to come up with a working example of what you want in a front end first. Then, you can figure out how to transform your notebook.

POSTED BY: Carl Woll
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract