Search code examples
wolfram-mathematicamathematica-frontendmathematical-expressions

How to create a notebook with a properly formatted expression


I have a Mathematica expression generated by another program, which I would like to open in a notebook, properly formatted. For instance, the other program generates this:

Plot[{Exp[x],Interpolation[Table[{k/5,Exp[(k-1/2)/5]},{k,0,5}],
InterpolationOrder->0][x]},{x,0,1},Filling->{1->{{2},{Yellow,Orange}}},
PlotLabel->Style["Formatting",Blue,FontFamily->"Courier"]]

The text is written into a file, crudely suffixed ".nb", and launched, and the expression opens in a notebook without formatting. To achieve formatting, writing a file manually with BoxData seems impractical.

The file is actually being launched from .Net using Process.Start("filename.nb"), but a command line launch seems equally problematic.


Solution

  • Here is the solution I adopted. Thanks for all the help.

    The main step of the solution is to format the command via the kernel:-

    FullForm[ToBoxes[
      Defer[Plot[{Exp[x], 
         Interpolation[Table[{k/5, Exp[(k - 1/2)/5]}, {k, 0, 5}], 
           InterpolationOrder -> 0][x]}, {x, 0, 1}, 
        Filling -> {1 -> {{2}, {Yellow, Orange}}}, 
        PlotLabel -> 
         Style["Formatting", Blue, FontFamily -> "Courier"]]]]]
    

    Then the formatted data is encapsulated to create a notebook:-

    Notebook[{Cell[BoxData[
    
    ... ( inserted box-formatted output ) ...
    
    ], "Input"]
    },
    WindowSize->{615, 750},
    WindowMargins->{{328, Automatic}, {Automatic, 76}},
    StyleDefinitions->"Default.nb"
    ]
    

    This is written to a file, suffixed ".nb". All fine and dandy.

    This approach works well for multi-statement blocks of code, but some additional processing was included to format a single function call of the form Function[expression, options] to add a line-break before each option. Here is the C# code used to produce both types of output:-

    public static class MathematicaHelpers
    {
        public static string CreateNotebook(string mathCommand, string fileLocation, MathKernel kernel, bool addNewLines)
        {
            if (addNewLines) {
                mathCommand = string.Format("{0}{1}{2}", "Module[{boxoutput,b2},boxoutput=FullForm[ToBoxes[Defer[", mathCommand, "]]];b2=boxoutput[[1,1,3,1]];boxoutput[[1,1,3,1]]=Join[Flatten[Riffle[Partition[b2,2],\"\\[IndentingNewLine]\"],1],{\"\\[IndentingNewLine]\",Last[b2]}];boxoutput]");
            } else {
                mathCommand = string.Format("{0}{1}{2}", "FullForm[ToBoxes[Defer[", mathCommand, "]]]");
            }
            fileLocation = Path.ChangeExtension(fileLocation, ".nb");
    
            mathCommand = ComputeMathCommand(mathCommand, kernel);
            mathCommand = string.Format("{0}{1}{2}", "Notebook[{Cell[BoxData[", mathCommand,
                                        "], \"Input\"]},WindowSize->{615, 750}, WindowMargins->{{328, Automatic}, {Automatic, 76}},StyleDefinitions->\"Default.nb\"]");
    
            File.WriteAllText(fileLocation, mathCommand);
            return fileLocation;
        }                             
    
        private static string ComputeMathCommand(string command, MathKernel kernel)
        {
            kernel.Compute(command);
            return kernel.Result.ToString();
        }
    }