13
$\begingroup$

Is there an option to delete every comment enclosed within (* *)s for a whole notebook? Or is it possible to do it with some string processing?

$\endgroup$
6
  • 3
    $\begingroup$ Converting a cell to StandardForm eliminates comments in the cell. Select all Input cells in the notebook by option-clicking (on a Mac, I don't know the Windows keyboard equivalent) on the cell bracket of any Input cell, and use Cell > Convert To > StandardForm (shift-command-N) to remove comments in the whole notebook. Be aware that reformatting a cell will also eliminate any manual formatting, such as extra carriage returns you may have put in to improve readability of your code, so use with caution. $\endgroup$ Commented Jul 29, 2019 at 2:27
  • $\begingroup$ Do you want to leave empty comments, or do you want to remove comments altogether? (The body seems to suggest the former and the title the latter.) $\endgroup$ Commented Jul 29, 2019 at 12:57
  • $\begingroup$ @Peter Mortensen To remove all comments including the (* *) pair, not leaving empty comments. Sorry for any confusion. $\endgroup$ Commented Jul 29, 2019 at 15:03
  • $\begingroup$ @Daniel W selecting the cells and converting to StandardForm is a great idea. Thank you. $\endgroup$ Commented Jul 29, 2019 at 20:52
  • $\begingroup$ @nanjun Kuba’s answer is a better long term solution, which is why I put my answer as a comment. That said, sometimes all you are looking for is a quick set of keystrokes, and I have always liked the “select all cells of this type” trick. $\endgroup$ Commented Jul 31, 2019 at 23:39

2 Answers 2

19
$\begingroup$

String processing is not needed, fortunately because you'd have to detect nested string/comment patterns. It is easy with existing box structure though:

deleteComments[] := deleteComments @ EvaluationNotebook[]; deleteComments[nb_NotebookObject] := ( SelectionMove[nb, All, Notebook] ; NotebookWrite[nb, DeleteCases[NotebookGet[nb], RowBox[{"(*", ___, "*)"}], Infinity]] ) 

You can run deleteComments[] from your notebook or target any notebook you wish.

$\endgroup$
2
  • $\begingroup$ Is it possible to condense your two definitions into a single one using a default argument? $\endgroup$ Commented Jul 29, 2019 at 13:47
  • 1
    $\begingroup$ @AccidentalFourierTransform but then you'd have to have a HoldAll attribute to not evaluate EvaluationNotebook[] too early. Or some kind of Unevaluated shenanigans. So this is the way I write such functions. $\endgroup$ Commented Jul 29, 2019 at 13:50
2
$\begingroup$

Thanks a lot for the solution provided in the Kuba's answer and bug alert in my previous improved solution by Michael E2. The original solution is elegant, but it has two flaws. First, it fails on cells that are completely commented out; ones that don't even contain a blank line before or after the comment. In that case, BoxData[] is left without an argument. Second, it also fails on all multi-star comments like (** sth **) or (********) placed anywhere, leaving them intact.

Examining the commented out expressions in low level form using Shift+Ctrl+E reveals that comments with multiple *'s always follow the pattern BoxData[RowBox[{"(*", ___, s}]], where s stands for "*)" or "**)" or "***)", ..., etc. So here I am posting the fix, it works as expected for me. The same commentary RowBox pattern must be present in both the replacement and the deletion, hence the use of With:

deleteComments[] := deleteComments[EvaluationNotebook[]]; deleteComments[nb_NotebookObject] := With[{(* comment RowBox pattern: *) cpat = RowBox[{"(*", ___, _?(And[StringQ[#], StringMatchQ[#, RegularExpression["\\*+\\)"]]] &)}] }, SelectionMove[nb, All, Notebook, AutoScroll -> False]; NotebookWrite[nb, DeleteCases[NotebookGet[nb] /. BoxData[cpat] -> BoxData[""], cpat, Infinity, Heads -> False], AutoScroll -> False] ] 

Any further testing would be greatly appreciated!

$\endgroup$
2
  • 2
    $\begingroup$ Note that it still fails on comments like (** Hi **). Sigh. +1 anyway :) $\endgroup$ Commented Aug 26, 2024 at 12:30
  • $\begingroup$ Now the edited version should work as expected. $\endgroup$ Commented Aug 28, 2024 at 19:56

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.