19

How to select and delete all Output cells in multiple notebooks programmatically without needing to (manually) opening them?

How to define a hot key for deleting all Output cells within a notebook from that notebook?

user13253
  • 8,666
  • 2
  • 42
  • 65
  • Maybe some useful information here. – b.gates.you.know.what Nov 01 '12 at 15:06
  • I think this is answered in the answers to this, as @b.gatessucks points out. – acl Nov 01 '12 at 15:21
  • I assume you know about the delete all output cell option in the Cell menu? If so it should be straightforward to assign a key to this (cf @acl and @b.gatessucks)? But may be you want a non interactive option? – chris Nov 01 '12 at 15:37
  • Actually the linked in the comments thread does not show simplest menu-wise solution. – Vitaliy Kaurov Nov 01 '12 at 15:41
  • Both how to do this programmatically on multiple notebooks, and how to do this from within the notebook using a hot key. From the referenced threads, it's not clear where to put KeyEventTranslations.tr? Can i put it some where in $UserBaseDirectory? – user13253 Nov 01 '12 at 15:41
  • 1
    Yes, you put it in $UserBaseDirectory. If the original is at $InstallationDirectory/foo/bar/file.tr, then you mirror the tree and copy it to $UserBaseDirectory/foo/bar/file.tr – rm -rf Nov 01 '12 at 16:03
  • by the way, you can hold Alt + click on a cell to select all cells of that type. i use this for deleting error output – amr Jul 26 '13 at 23:55

4 Answers4

16

Without adressing the hotkey issue (you could add a menu entry, or simply put an appropriate Button in your notebook), here is one variety that uses NotebookDelete and can be modified to include different CellStyles as well. The first argument nb defines which notebook to work on, the second argument styles defines the styles of to-be-deleted cells:

CleanNotebook[nb_: SelectedNotebook[],styles_: {"Output"}] := 
   (NotebookFind[nb, #, All, CellStyle];
    NotebookDelete[nb];) & /@ styles

Together with NotebookOpen, NotebookSave and NotebookClose and related functions you should be able to work on arbitrary notebooks programmatically.

Example:

docpath = 
  ToFileName[{$InstallationDirectory, "Documentation", "English", 
    "System"}, "ExampleData"];

nb = NotebookOpen[ToFileName[docpath, "document.nb"]]

Mathematica graphics

CleanNotebook[nb]

Take care what other styles you choose, they´ll be gone for good...

Edit: You may also use the Option Visbible->False to supress the opening of a window for this notebook. This seems useful for batch processing (especially if Dynamic stuff is involved, because this will probably not trigger if invisible), but takes additional care to save and close programmatically because invisble windows do not show up in the menu bar.

Example:

doc = ToFileName[{$InstallationDirectory, "Documentation", "English", 
    "System", "ExampleData"}, "document.nb"];

bak = ToFileName[$TemporaryDirectory, "document_clean.nb"];

nb = NotebookOpen[doc, Visible -> False];
CleanNotebook[nb];
NotebookSave[nb, bak]
NotebookClose[nb]

NotebookOpen[doc];    
NotebookOpen[bak, Visible -> True];

There is still an issue with the Visible option being saved in the backup notebook and hiding when reopened (thus re-setting Visible->True).

Yves Klett
  • 15,383
  • 5
  • 57
  • 124
  • Is that a typo that the second instance of SelectedNotebook[] should be nb? – user13253 Nov 02 '12 at 02:02
  • If i'm applying the function should the first argument be simply the file name (a _String expression) or that wrapped with NotebookOpen? – user13253 Nov 02 '12 at 02:32
  • @MonkeyKing: Correct! Fixed... – Yves Klett Nov 02 '12 at 06:49
  • @MonkeyKing: If you use NotebookOpen it returns a NotebookObject. This NotebookObject can be used as a handle for subsequent actions. See edit. – Yves Klett Nov 02 '12 at 06:57
  • If you use this method on many notebooks, wouldn't it cause many notebooks quickly open on your screen and close? Is there a way to open them for kernel but not visually to human? – user13253 Nov 02 '12 at 14:41
  • @MonkeyKing do you just want to hide/minimize the notebooks using the frontend or do you need a sole kernel session without a frontend? – Yves Klett Nov 02 '12 at 19:08
  • It doesn't have to be a pure kernel session. I was just double checking if there's a way (such as an option to NotebookOpen) to open the notebooks without having it flash (i.e. quickly open and close in a sec on screen) on screen, if i have thousands of notebooks to process, say. – user13253 Nov 03 '12 at 00:41
  • Also, asking thousands of notebooks to open and close continuously seems prone to crash FE and/or Mathematica. – user13253 Nov 03 '12 at 03:45
  • @MonkeyKing re stability: can't say. You'd have to test this. Your question does not mention multi-kilo notebooks. Minimizing and/or working from the kernel should be possible but I'd revommend a new/revised question for that. – Yves Klett Nov 04 '12 at 11:05
7

This is how you do it through menus, As correctly noted in the comment this is equivalent to the shortcut ALT+C >> L >> ENTER.

enter image description here

Vitaliy Kaurov
  • 73,078
  • 9
  • 204
  • 355
5

Update December 6th: There is an updated version (plus a bug fix for M9) working on Windows, MacOSX and Linux available and installable by

  Import["http://www.mertig.com/mykeys.m"]

On Windows (Mac does not work yet): Execute the following code in a notebook and restart Mathematica.

Then hitting F4 will delete all Output, Print and Message cells in the selected notebook, while pressing F8 will do so in all open notebooks which are not Wolfram Documentation notebooks. This was more difficult to program than it should be ...

$OverWriteUserBaseDirectoryKeyEventTranslations = True;
    mymenuitems="
       (* Delete all Output, Message and Print cells in the selected notebook *)
                 Item[KeyEvent[\"F4\"(*, Modifiers -> {\"Control\",\"Shift\"}*)], 
                 KernelExecute[
                   Module[{nb = SelectedNotebook[]},
                    Scan[Function[c, If[NotebookFind[nb, c, All, CellStyle, AutoScroll -> False] =!= $Failed,
                                    NotebookDelete[nb, AutoScroll -> False]]  
                             ],
                     {\"Message\", \"Output\", \"Print\"}
                    ];
                 SelectionMove[nb,After,Notebook];
              ]
            ], MenuEvaluator -> Automatic ],\n
  (* Delete all Output, Message and Print cells in all open notebooks *)
             Item[KeyEvent[\"F8\"], 
             KernelExecute[
               Module[{nbs = Notebooks[]},
                Quiet[nbs = Select[nbs,  Function[z, Not[StringMatchQ[ Replace[ NotebookFileName[z], $Failed :> \"\"],
                                                                           \"*Wolfram*Documentation*\"]]]]];
                    Do[
                    Scan[Function[c, If[NotebookFind[nb, c, All, CellStyle, AutoScroll -> False] =!= $Failed,
                                    NotebookDelete[nb, AutoScroll -> False]]  
                             ],
                     {\"Message\", \"Output\", \"Print\"}
                    ];
                 SelectionMove[nb,After,Notebook],
                {nb,nbs}]
              ]
            ], MenuEvaluator -> Automatic ],";
Quiet@CreateDirectory@FileNameJoin[{$UserBaseDirectory,"SystemFiles","FrontEnd","TextResources",$OperatingSystem}];
mykeyeventtrans=FileNameJoin[{$UserBaseDirectory,"SystemFiles","FrontEnd","TextResources",$OperatingSystem,"KeyEventTranslations.tr"}];
If[$OverWriteUserBaseDirectoryKeyEventTranslations===True,
    If[FileExistsQ[mykeyeventtrans],DeleteFile@mykeyeventtrans];
    CopyFile[FileNameJoin[{$InstallationDirectory,"SystemFiles","FrontEnd","TextResources",$OperatingSystem,"KeyEventTranslations.tr"}],mykeyeventtrans]
];
keytext=Import[mykeyeventtrans,"Text"];
mykeytext=StringReplace[keytext,"EventTranslations[{":>StringJoin["EventTranslations[{\n",mymenuitems,"\n"]];
Export[mykeyeventtrans,mykeytext,"Text"];
Rolf Mertig
  • 17,172
  • 1
  • 45
  • 76
  • How about including Undo option? Instead of NotebookDelete[..] use MathLink\CallFrontEnd[FrontEnd`SelectionAddCellTags[nb, {"$deleted"}]]and then just before the last commandSelectionMove[..]insert thisIf[NotebookFind[nb, "$deleted", All, CellTags, AutoScroll -> False] =!= $Failed, MathLink`CallFrontEnd[FrontEnd`SelectionRemoveCellTags[nb, {"$deleted"}]]; FrontEndTokenExecute["Clear"]];` – Vladimir Apr 14 '13 at 18:37
5

Yves Klett's answer is still pretty simple, but I thought I would add an alternative V9 solution using Cells

nb = EvaluationNotebook[]; (* change as desired *)
cells = Cells[nb, CellStyle -> {"Output"}];
CopyToClipboard @ NotebookRead @ cells; (* optional - saves cells for pasting *)
NotebookDelete[cells]

Beware: Pasting the cells back into the notebook will replace the current selection. It is not an "undo" command. It potentially could save an enormous amount of data, which you might not always want.

Here's a modification of Yves Klett's function CleanNotebook, with an improvement suggested by @CarlWoll:

deleteStyle[nb_: SelectedNotebook[], styles_: {"Output"}] :=
  With[{cells = Flatten[Cells[nb, CellStyle -> styles]]},
    (* CopyToClipboard@NotebookRead@cells; (*optional*) *)
    NotebookDelete[cells]
   ]

Again, there's no "undo" for this, so be careful.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • 2
    Cells[nb, CellStyle -> {"Input", "Output"}] selects both "Input" and "Output" cells, no need to use Map. – Carl Woll Aug 26 '17 at 00:37
  • @CarlWoll Thanks. I didn't know that. – Michael E2 Aug 26 '17 at 11:51
  • 1
    The advantage of this approach (as compared to Yves Klett's) is that it won't open collapsed cell groups containing the cells to delete. But for some reason it is much slower and requires more memory (taken by the FrontEnd) even without CopyToClipboard. On a Notebook of size 252 Mb the Yves Klett's CleanNotebook[] takes 2.5 sec to evaluate and the FrontEnd takes 1.88 Gb of memory ("Private Set" according to Windows Task Manager), but deleteStyle[] takes 64.2 sec to evaluate and the FrontEnd takes 2.43 Gb of memory (fresh session). – Alexey Popkov Aug 26 '17 at 13:50
  • (OS Windows 7 x64, Mathematica 11.1.1) – Alexey Popkov Aug 26 '17 at 13:55
  • 1
    I'm very surprised both by wonderful efficiency of the NotebookFind + NotebookDelete approach and disappointing performance of the Cells + NotebookDelete approach... – Alexey Popkov Aug 26 '17 at 14:04