【问题标题】:How to create a notebook with a properly formatted expression如何创建具有正确格式表达式的笔记本
【发布时间】:2011-11-10 12:42:30
【问题描述】:

我有一个由另一个程序生成的 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 启动的,但命令行启动似乎同样有问题。

【问题讨论】:

  • 只是好奇......你用什么程序来生成它?
  • @belisarius - 使用 .Net 构建具有大量参数和参数的函数。它实际上不是像示例那样的绘图函数。

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


【解决方案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:-

Notebook[{Cell[BoxData[

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

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

这被写入一个文件,后缀为“.nb”。一切都很好。

这种方法适用于多语句代码块,但包含一些额外的处理来格式化 Function[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();
    }
}

【讨论】:

    【解决方案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 选项。

    【讨论】:

    • ToBoxes 允许仅使用内核将表达式转换为BoxForms
    • @Alexey - 谢谢。我得到了内核输出的某个地方: 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"]] ]]
    【解决方案3】:

    这个怎么样:

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

    在运行上面的代码之前。

    【讨论】:

    • 谢谢。有趣的是 ToExpression 与 MakeBoxes 一起使用。我可以确认它有效,例如FullForm[ToExpression[ToString[HoldForm[FullForm[expression]]], InputForm, MakeBoxes]] == FullForm[ToBoxes[Defer[expression]]]
    • @Chris 我想我潜意识里不喜欢Defer,可能是因为我不知道它的功能无法以其他更透明的方式实现的情况。
    【解决方案4】:

    您可以使用以下包装:

    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 命令来保存和关闭事物;)

    【讨论】:

    • 这有点接近我正在寻找的东西,但尽管尝试我无法从命令行执行它: CreateDocument[ExpressionCell[Defer[Plot[{Exp[x],Interpolation [表[{k/5,Exp[(k-1/2)/5]},{k,0,5}],InterpolationOrder->0][x]},{x,0,1},填充->{1->{{2},{Yellow,Orange}}},PlotLabel->Style["Formatting",Blue,FontFamily->"Courier"]]],"Input"]]
    • @Chris 您需要将代码包装在 DeveloperUseFrontEnd, again I mean use UseFrontEnd` 中的 Developer 上下文中。
    猜你喜欢
    • 2018-03-20
    • 2022-01-21
    • 2016-11-18
    • 1970-01-01
    • 2021-01-02
    • 2023-02-26
    • 2019-05-01
    • 1970-01-01
    • 2015-08-07
    相关资源
    最近更新 更多