While writing a response to a certain MSE question I made a function that tabulates code and comments. (See the definition below.)
Here is an example:
code = "
FoldList[(* reduction function *)
Plus,(* function to apply repeatedly *)
0,(* initial value *)
{1,2,3,3,100}(* arguments in repeated computations *)]";
GridOfCodeAndComments[
code,
"GridFunction" -> (Panel@Grid[#, Alignment -> Left] &)]
I have several problems with the implementation of GridOfCodeAndComments, the main one being that I have to give a string to the function instead of (commented) code.
For example, I would like to be able to write the tabulate code directly to GridOfCodeAndComments:
GridOfCodeAndComments[
FoldList[(* reduction function *)
Plus,(* function to apply repeatedly *)
0,(* initial value *)
{1, 2, 3, 3, 100}(* arguments in repeated computations *)],
"GridFunction" -> (Panel@Grid[#, Alignment -> Left] &)]
How can this be done? Any suggestions would be appreciated.
Another, minor problem in GridOfCodeAndComments is that the pattern for matching comments, comPat, is somewhat weak. How can it be improved?
Definition
ClearAll[GridOfCodeAndComments]
Options[GridOfCodeAndComments] = {"GridFunction" -> (Grid[#, Alignment -> Left] &)};
GridOfCodeAndComments[code_String, opts : OptionsPattern[]] :=
Block[{grData, codeLines, commentLines, comPat, gridFunc},
gridFunc = OptionValue["GridFunction"];
If[TrueQ[gridFunc === Automatic], gridFunc = (Grid[#, Alignment -> Left] &)];
(* Split the code into lines *)
codeLines = StringSplit[code, "\n"];
(* Split each line into a {code, comment} pair *)
comPat = ("(*" ~~ (Except["*"] ..) ~~ "*)");
grData =
Map[
If[StringFreeQ[#, "(*"], {#, ""},
StringCases[#, (x__ ~~ y : (comPat) ~~ z___) :> {x <> z, y}][[1]]
] &, codeLines];
(* Style the code and comments *)
grData[[All, 1]] = Map[Style[#, "Input"] &, grData[[All, 1]]];
grData[[All, 2]] =
Map[Style[#, "CommentStyle" /. Options[$FrontEnd, AutoStyleOptions][[1, 2]]] &, grData[[All, 2]]];
(* Show result *)
gridFunc[grData]
];


CellEvaluationFunctionor$PreReadto prevent that. As for your comment matching, I think you might be better off splitting by"*)"than by line, then splitting at the first(*. Of course this assumes you don't have any(*or*)in your input code. That could be fixed by parsing on the box-structure, though and passing an alternate format to your function (as code, comment pairs, maybe). Otherwise it's not really worth it. $\endgroup$