Pregunta

Tengo una expresión de Mathematica generada por otro programa, que me gustaría abrir en un cuaderno, formateado correctamente. Por ejemplo, el otro programa genera esto:

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

El texto se escribe en un archivo, sufijo crudo ".nb", y se lanza, y la expresión se abre en un cuaderno sin formatear. Para lograr el formato, escribir un archivo manualmente con BoxData parece poco práctico.

El archivo en realidad se está lanzando desde .net usando Process.Start ("FileName.nb"), pero un lanzamiento de la línea de comandos parece igualmente problemático.

¿Fue útil?

Solución 4

Aquí está la solución que adopté. Gracias por toda la ayuda.

El paso principal de la solución es formatear el comando a través del núcleo:-

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

Luego, los datos formateados están encapsulados para crear un cuaderno:-

Notebook[{Cell[BoxData[

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

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

Esto se escribe en un archivo, sufijo ".nb". Todo bien y dandy.

Este enfoque funciona bien para bloques de código de estados múltiples, pero se incluyó un procesamiento adicional para formatear una llamada de función única de la función de formulario [expresión, opciones] para agregar un descanso de línea antes de cada opción. Aquí está el código C# utilizado para producir ambos tipos de salida:-

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

Otros consejos

Qué tal esto:

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

Lo probé y parece funcionar (importando desde el archivo simple, exportando al que luego abrirá). Esto crea cajas explícitas, pero con muy poco esfuerzo en el lado del usuario. No probé, pero debería poder ejecutar este código en el modo de script, desde la línea de comando.

EDITAR

Para probar desde Mathematica, puede usar EG

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

Antes de ejecutar el código anterior.

Puedes usar la siguiente envoltura:

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

Luego, los comandos NotebookSave y NotebookClose se pueden usar para guardar y cerrar la cosa;)

A menos que cree el BoxData Expresiones explícitamente no hay forma de formatear su expresión sin invocar al menos el interfaz de Mathematica.

Lo más cercano que se me ocurre es que agregas lo siguiente:

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

que formatea automáticamente el Plot comando cuando se evalúa la celda. (Por cierto: probablemente deberías agregar Evaluate frente a la lista o agregue el (no tan bien documentado) Evaluate->True opción.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top