Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I often have a large function to which I add inline comments, but then I can't see the forest for the trees. How can I make a tool that extracts the comments and tokens within them to generate an overview or structured outline of the large complex function? For instance:

 BigNastyFunction[input_List, xSpecArg_, ySpecArg_, OptionsPattern[]] := 
 Module[
 {
    (*1:1 Local variables*)
   data, ySpecContinousQ, xSpecContinousQ, groupsQ, joinedCounts, colors, ymin, ymax, xmin, 

   (*1:2 Option variables*)
   axesLabelsQ, barOrigin, background, diskSizeScaling, displayFunction, frameQ
 }

  (*2:1 Check for null Input*)
  If[times === {}, Return[$Failed]];

  (*2:2:1 Check for groups *)
  check1 = Depth[input] === 4;  
  (*2:2:2 Check for nongroups *)
  check2 = Depth[input] === 3;  

  etc...

Would be transformed into something like:

Outline of BigNastyFunction

Part 1.

.....Step 1. Local variables

.....Step 2. Option variables

Part 2.

.....Step 1. Check for null Input

.....Step 2.

..........a) Check for groups

..........b) Check for nongroups

share|improve this question
    
Do you program in the notebook FrontEnd or in Wolfram Workbench or in vi ? –  Rolf Mertig Sep 12 '12 at 23:26
    
@RolfMertig You forgot Emacs :) –  belisarius Sep 12 '12 at 23:29
1  
@belisarius no, I did think about it. but then I did not want to bore people too much and stick with the most common editors. –  Rolf Mertig Sep 12 '12 at 23:35
    
@RolfMertig I can program in either. –  M.R. Sep 13 '12 at 0:08
    
At risk of stating the obvious, you could always just change the comment highlighting color to something more visible, perhaps temporarily, e.g. SetOptions[$FrontEndSession, AutoStyleOptions -> {"CommentStyle" -> {FontColor -> RGBColor[1., 0.5, 0.], ShowAutoStyles -> False, ShowSyntaxStyles -> False, AutoNumberFormatting -> False}} ] –  Mr.Wizard Sep 13 '12 at 7:16
add comment

2 Answers 2

up vote 8 down vote accepted

I would suggest something more simple-minded than Rolf's sophisticated implementation:

Clear[extractComments];
extractComments[boxes_] :=
  StringJoin@
    Riffle[
      Cases[boxes, 
          r : RowBox[{"(*", ___, "*)"}] :> 
              StringJoin@Cases[r, _String, Infinity], Infinity],
      "\n"];

and the palette:

CreatePalette[
  Button["Comments",
    With[{read = NotebookRead[SelectedNotebook[]]},
      SelectionMove[SelectedNotebook[], After, Cell];
      NotebookWrite[SelectedNotebook[], Cell[extractComments[read]]]
    ]
  ]]

You select your function's cell and press the "Comments" button. This seems to work in simple cases I tested. You can modify the extractComments function to implement more complex logic that would categorize the comments according to their hierarchy etc.

share|improve this answer
    
Nice, though this will get you all comments, not just those with ":" in it. –  Rolf Mertig Sep 13 '12 at 0:46
    
Maybe there should be some kind of MDoc, like JavaDoc ... And then these things would be easy ... –  Rolf Mertig Sep 13 '12 at 0:48
    
@RolfMertig re - not just those with ":" - indeed, but it is very easy to postprocess, to filter out those without it. Re: MDoc - indeed, but I thought something like this existed already? Of course, this can work only of this becomes a widely used standard. –  Leonid Shifrin Sep 13 '12 at 0:50
    
@LeonidShifrin Nice comment grabber. But I think the project of an general inline documentation utility remains a worthy goal. –  M.R. Sep 13 '12 at 2:53
    
@LeonidShifrin how might I adapt this to WorkBench and extracting comments for a symbol from a file? –  M.R. Sep 17 '12 at 17:55
show 1 more comment

OK, FrontEnd: After creating the "overview" button below just click first on your function definition and then on the button and under the function definition you will get (nearly) what you want, i.e. :

Part 1.

Step 1. Local variables

Part 1.

Step 2. Option variables

Part 2.

Step 1. Check for null Input

Part 2.

Step 2.:1 Check for groups

Part 2.

Step 2.:2 Check for nongroups

  CreatePalette@Cell[BoxData[
 ButtonBox["overview",
  ButtonFunction:>Block[{$CellContext`com}, SelectionMove[
          SelectedNotebook[], All, CellContents]; $CellContext`com = 
     ExportString[
       StringDrop[
        Apply[StringJoin, 
         StringCases[
          Apply[StringJoin, $CellContext`RER = ReplaceRepeated[
                 NotebookRead[
                  InputNotebook[]], RowBox[
                   Condition[
                    Pattern[$CellContext`x, 
                 BlankSequence[]], 
                Not[
                 FreeQ[$CellContext`x, RowBox]]]] :> Apply[RowBox, 
                   ReplaceAll[{$CellContext`x}, RowBox[{
                       Pattern[$CellContext`y, 
                        BlankSequence[]]}] :> $CellContext`y]]]], {
          StringExpression["(*", 
             Shortest[
              Pattern[$CellContext`i, 
                   Blank[]]], ":", 
                 Shortest[
                  Pattern[$CellContext`j, 
               BlankSequence[]]], 
             Shortest[
              Pattern[$CellContext`str, 
                   BlankSequence[]]], "*)"] :> {
                 StringExpression["\nPart ", $CellContext`i, 
                  StringJoin[".\n", "Step "], $CellContext`j, 
                  "."], $CellContext`str}}]], 1], "Text"]; SelectionMove[
          SelectedNotebook[], After, Cell]; NotebookWrite[
          SelectedNotebook[], 
          Cell[$CellContext`com, "Text"]]],
  Evaluator->Automatic]]]
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.