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?
2 Answers
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.
- $\begingroup$ Is it possible to condense your two definitions into a single one using a default argument? $\endgroup$AccidentalFourierTransform– AccidentalFourierTransform2019-07-29 13:47:24 +00:00Commented Jul 29, 2019 at 13:47
- 1$\begingroup$ @AccidentalFourierTransform but then you'd have to have a
HoldAllattribute to not evaluateEvaluationNotebook[]too early. Or some kind ofUnevaluatedshenanigans. So this is the way I write such functions. $\endgroup$Kuba– Kuba2019-07-29 13:50:22 +00:00Commented Jul 29, 2019 at 13:50
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!
- 2$\begingroup$ Note that it still fails on comments like
(** Hi **). Sigh. +1 anyway :) $\endgroup$Michael E2– Michael E22024-08-26 12:30:10 +00:00Commented Aug 26, 2024 at 12:30 - $\begingroup$ Now the edited version should work as expected. $\endgroup$hlediks– hlediks2024-08-28 19:56:21 +00:00Commented Aug 28, 2024 at 19:56
StandardFormeliminates 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$(* *)pair, not leaving empty comments. Sorry for any confusion. $\endgroup$StandardFormis a great idea. Thank you. $\endgroup$