7
$\begingroup$

In order to discuss this, I think it's easiest to start with two definitions. (If there's a standard terminology, please comment.)

  1. Working notebook: a notebook that is open and in memory.
  2. Disk notebook: a notebook that is saved to the disk.

Typically, whenever we are editing a notebook foo.nb, it is a working notebook. When we save the notebook, the entirety of foo.nb is copied to the disk, making it a disk notebook.

Previously, it has been noted that, for various reasons, it is desirable to save everything in a notebook except the output cells, which increase the file-size (especially with graphics).

The answer gives a method of deleting output cells upon closing the window in which the notebook is being viewed. Note that means that the working notebook may have been saved to the disk notebook (hopefully) many times throughout a session with all output cells. Upon closing the window and saving, all output cells are deleted and the working notebook is saved (now sans output cells) to the disk notebook.

Primarily for purposes of version control, I would like to avoid the disk notebook ever containing output cells.

In the comments to the answer, the following solution was suggested:

SetOptions[
  EvaluationNotebook[],
  NotebookEventActions -> 
    {
      {"MenuCommand", "Save"} :>              
      FrontEndExecute[FrontEndToken["DeleteGeneratedCells"]]
    }
];

This works, except that the working notebook deletes all its output cells whenever it is saved to the disk notebook. This is undesirable.

Is there any way to save the working notebook sans output to the disk notebook?

Note that it would be best if the answer avoided using separate disk notebooks (unless they were temporary and cleaned-up), which I think is easier, but missing the point, to some extent.

$\endgroup$
  • $\begingroup$ So saving a separate "clean" vc notebook is undesirable? $\endgroup$ – Yves Klett May 14 '14 at 19:05
  • $\begingroup$ I'd make additional shortkey for your purposes. delete_generated_cells+save+close. If I'm not mistaken about your needs. ps. what "sans" is? $\endgroup$ – Kuba May 14 '14 at 19:10
  • 2
    $\begingroup$ @Kuba sans == without, but a lot more sophisticated/polyglot ;-) $\endgroup$ – Yves Klett May 14 '14 at 19:11
  • $\begingroup$ @YvesKlett, correct, a separate, "clean" (what's vc?) notebook would be less-desirable (but if that's all way can do, it's ok). I think it would make using it more "clunky." Also, I'll try to ask questions sans polyglot in the future ;) $\endgroup$ – Rico Picone May 14 '14 at 19:21
  • $\begingroup$ No no, please polyglot away! I like polyglot (honestly). My abbreviation was clumsy, I meant version control (darn tablet makes me want to save on characters). $\endgroup$ – Yves Klett May 14 '14 at 19:27
4
$\begingroup$

This is exactly the automatic behavior when using .m ("package") files, rather than .nb (notebook) files, in the Mathematica front end. You can enter and evaluate input cells (which are Code-style cells in .m files rather than Input-style cells) as usual, and the output cells display in the .m file, as for a notebook file. The output cells never save with the package file, however.

Package files are also far superior to notebook files for version control in other ways, primarily because the code cells are saved in InputForm format, rather than in complicated Cell expressions using BoxData. They also do not save meta-data such as the file outline cache and cell change times, which complicate version control, although these features can be turned off for notebooks, too.

Basically, if you want to do version control, you should use package files, unless you need to save the output cells, or other data such as cell tags.

If you want to convert an existing notebook to a package file, just "Save As", with "Save As Type" .m file, but keep in mind that the Input cells in your .nb file must be set as initialization cells (under the Cell > Cell Properties menu) for them to be converted to Code cells in the new .m file.

$\endgroup$
  • $\begingroup$ Thanks, Simon. I use m-files, but I usually edit them in an external editor, so I hadn't realized you can treat them like a notebook in some ways (with sections, cells, etc.). It appears that if you'd like to add sections directly in a text editor, the syntax is (* ::Section:: *)(*Section Name*). $\endgroup$ – Rico Picone Sep 3 '14 at 0:54
3
$\begingroup$

Simon's answer provides a good way to save clean versions of the file one is working on, but it is not particularly easy to automate. In particular, I was looking for a way to store two copies of the notebook I was working on - one with the output for ease of reading, and another one with the output stripped to commit to source control - and this should ideally happen automatically when saving the main file.

Saving to a package file programmatically can be done as explained in this answer, and this leads to the following options code,

SetOptions[
  EvaluationNotebook[],
  NotebookEventActions->{
    {"MenuCommand","Save"}:>(
      FrontEndTokenExecute[
        FrontEnd`InputNotebook[],
        "SaveRename",
        {"CleanFile.m", "Package"}
      ];
      NotebookSave[];
    )
  }
];

which will save a clean version to CleanFile.m whenever the main file is saved. I'm not sure how much this matches the behaviour the OP was looking for, but this is probably still the best place to document it.

$\endgroup$

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.