如何使用格式正确的表达式创建笔记本

时间:2011-09-05 10:30:33

标签: wolfram-mathematica mathematica-frontend mathematical-expressions

我有一个由另一个程序生成的Mathematica表达式,我想在笔记本中打开,格式正确。例如,另一个程序生成:

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"]]

文本被写入文件,粗略地加上后缀“.nb”,然后启动,表达式在没有格式化的笔记本中打开。要实现格式化,使用BoxData手动编写文件似乎不切实际。

该文件实际上是使用Process.Start(“filename.nb”)从.Net启动的,但命令行启动似乎同样存在问题。

4 个答案:

答案 0 :(得分:4)

这个怎么样:

Export["C:\\Temp\\formatTest1.nb", 
   ToExpression[Import["C:\\Temp\\formatTest.nb", "Text"], InputForm, MakeBoxes]]

我测试了它似乎工作(从普通文件导入,导出到您将打开的那个)。这确实创建了明确的框,但用户方面的努力很少。我没有测试,但您应该能够从命令行以脚本模式运行此代码。

修改

要在Mathematica中进行测试,您可以使用例如

Export["C:\\Temp\\formatTest.nb", 
  ToString@HoldForm@FullForm@
    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"]], 
  "Text"]

在运行上面的代码之前。

答案 1 :(得分:2)

您可以使用以下包装:

nb = CreateWindow[
     DocumentNotebook[{
       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"]]
     }]]

然后命令NotebookSave和NotebookClose可以用来保存和关闭东西;)

答案 2 :(得分:2)

除非您明确创建BoxData表达式,否则无法在不实际调用Mathematica FrontEnd的情况下格式化表达式。

我能想到的最接近的是你添加以下内容:

SelectionMove[EvaluationNotebook[], Next, EvaluationCell]; 
FrontEndExecute[{FrontEndToken[FrontEnd`InputNotebook[], 
                 "SelectionConvert", "StandardForm"]}]; 
Plot[{Exp[x], Interpolation[Table[{k/5, Exp[(1/5)*(k - 1/2)]}, {k, 0, 5}], 
                InterpolationOrder -> 0][x]}, {x, 0, 1}, 
  Filling -> {1 -> {{2}, {Yellow, Orange}}}, 
  PlotLabel -> Style["Formatting", Blue, FontFamily -> "Courier"], 
  Evaluated -> True]
SelectionMove[EvaluationNotebook[], After, GeneratedCell]; 

在评估单元格时自动格式化Plot命令。 (顺便说一句:您可能应该在列表前添加Evaluate或添加(不太好记录的)Evaluate->True选项。

答案 3 :(得分:1)

这是我采用的解决方案。感谢您的帮助。

解决方案的主要步骤是通过内核格式化命令: -

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"]]]]]

然后封装格式化数据以创建笔记本: -

Notebook[{Cell[BoxData[

... ( inserted box-formatted output ) ...

], "Input"]
},
WindowSize->{615, 750},
WindowMargins->{{328, Automatic}, {Automatic, 76}},
StyleDefinitions->"Default.nb"
]

这是写入一个后缀为“.nb”的文件。一切都很好,花花公子。

这种方法适用于多语句代码块,但是包含了一些额外的处理来格式化函数[expression,options]形式的单个函数调用,以在每个选项之前添加换行符。以下是用于生成两种输出类型的C#代码: -

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();
    }
}