Al fin después de tanto trabajar hemos dado con el resultado de esta cuestión que ciertos de nuestros usuarios de esta web han presentado. Si tienes algún dato que aportar no dudes en aportar tu conocimiento.
Solución:
El punto principal es que Jupyter
es una estructura plana, pero el Notebook
es una estructura anidada. Me tomó mucho tiempo resolver este problema por completo.
Gracias por el consejo de @ b3m2a1, los problemas de texto se han reducido.
Ahora todavía hay algún problema:
- La reproducción de imágenes tiene bordes incomprensibles
- No se encontraron más problemas, coloque los archivos de prueba en GalAster / JupyterConvert si encuentra alguno.
El archivo de prueba se puede descargar desde: Test / Notebook2Jupyter / code.nb
(* ::Package:: *)
Notebook2Jupyter::usage = "";
Begin["`Private`"];
JupyterInputCell::usage = "";
JupyterCodeCell::usage = "";
JupyterMarkdownCell::usage = "";
JupyterRawCell::usage = "";
Options[Notebook2Jupyter] = ;
Notebook2Jupyter[nb_NotebookObject, o : OptionsPattern[]] := Block[
jp = $JupyterTemplate, parsed, cells,
parsed = Flatten[parseCell /@ Cells[nb]];
cells = SequenceSplit[parsed,
text__JupyterMarkdownCell :> JupyterMarkdownBuild[First /@ text],
in_JupyterInputCell, other___JupyterCodeCell :> JupyterCodeBuild[First /@ in, other]
];
jp["cells"] = cells;
[email protected]
;
];
Notebook2Jupyter[nb_NotebookObject, path_String, o : OptionsPattern[]] := Block[
jp = Notebook2Jupyter[nb, o],
[email protected][path, jp, "JSON"]
];
JupyterMarkdownBuild[text_List] := <|
"cell_type" -> "markdown",
"source" -> StringRiffle[text, "nn"]
|>;
JupyterCodeBuild[code_] := <|
"cell_type" -> "code",
"source" -> code
|>;
JupyterCodeBuild[code_, out_] := <|
"cell_type" -> "code",
"source" -> code,
"outputs" ->
<
|>;
JupyterCodeBuild[code_, print__, out_] := <|
"cell_type" -> "code",
"source" -> code,
"outputs" -> [email protected]
<
|>;
(* ::Chapter:: *)
(*Cell*)
(* ::Section:: *)
(*Template*)
$JupyterTemplate = <|
"metadata" -> <||>
|>;
(* ::Section:: *)
(*Default*)
parseCell[co_CellObject] := parseCell[NotebookRead[co], co];
parseCell[c_Cell, co_CellObject] := parseCell[#2, #, co]& @@ c;
parseCell[s_, o___] := (
Echo[Inactive[parseCell][s, o], "Todo: "];
[email protected]["[//]: # (No rules defined for ``)nn", s]
);
(* ::Section:: *)
(*Normal*)
parseCell["Title", data_, co_CellObject] := JupyterMarkdownCell["# " <> [email protected]];
parseCell["Subtitle", data_, co_CellObject] := JupyterMarkdownCell["## " <> [email protected]];
parseCell["Chapter", data_, co_CellObject] := JupyterMarkdownCell["### " <> [email protected]];
parseCell["Section", data_, co_CellObject] := JupyterMarkdownCell["#### " <> [email protected]];
parseCell["Subsection", data_, co_CellObject] := JupyterMarkdownCell["##### " <> [email protected]];
parseCell["Subsubsection", data_, co_CellObject] := JupyterMarkdownCell["###### " <> [email protected]];
parseCell["Text", data_, co_CellObject] := JupyterMarkdownCell[[email protected]];
parseCell["WolframAlphaShort", data_String, co_CellObject] := JupyterMarkdownCell[data];
(* ::Section:: *)
(*Code*)
toASCII[a_] := StringTake[ToString[a, InputForm, CharacterEncoding -> "ASCII"], 10, -2];
parseCell["Input", boxes_, co_CellObject] := Block[
expr = MakeExpression[[email protected], StandardForm], out,
out = expr //.
HoldComplete[ExpressionCell[a___, Null, b___]] :> StringJoin[toASCII[[email protected]], ";n", toASCII[[email protected]]],
HoldComplete[ExpressionCell[a_]] :> toASCII[[email protected]]
;
JupyterInputCell[out]
];
parseCell["Print", boxes_, o___] := JupyterCodeCell[[email protected]`CallFrontEnd[ExportPacket[[email protected], "PlainText"]]];
parseCell["Echo", data___] := parseCell["Print", data];
parseCell["Message", data___] := parseCell["Print", data];
parseCell["Output", boxes_, co_CellObject] := Block[
dump = [email protected]`CallFrontEnd[ExportPacket[[email protected], "PlainText"]],
[email protected][
dump == "",
<|"image/png" -> ExportString[Rasterize[co, Background -> None], "Base64", "PNG", Background -> None]|>,
<|"text/plain" -> dump|>
]
];
(* ::Section:: *)
(*TeX*)
boxesToTeX = ToString[[email protected]#, TeXForm] &;
parseCell["Output", BoxData[FormBox[boxes_, TraditionalForm]], cellObj_CellObject] := TemplateApply["$$``$$nn", [email protected]];
(* ::Section:: *)
(*Pass*)
parseCell["Code", data___] := ;
parseCell[$Failed, data___] := ;
(* ::Chapter:: *)
(*Data*)
parseData[list_List] := parseData /@ list;
parseData[string_String] := string;
parseData[cell_Cell] := [email protected]@cell;
parseData[boxes_] := (
Echo[Inactive[parseData][boxes], "Todo: "];
[email protected]@boxes
);
parseData[data_BoxData] := List @@ (parseData /@ data);
parseData[data_TextData] := List @@ (parseData /@ data);
parseData[TemplateBox[text_String, link_String, "HyperlinkURL"]] := TemplateApply["[``](``)", text, link];
End[]
Esta nb2ipynb
La función toma el nombre de archivo del cuaderno como entrada y devuelve un cuaderno jupyter compatible con JWLS.
nb2ipynb = Module[
cellF = &,
ipynbF =
"cells" -> cellF @@@ #,
"metadata" -> "kernelspec" -> "display_name" -> "JWLS_2",
"language" -> "text",
"name" -> "jwls_2",
"language_info" -> "codemirror_mode" -> "mathematica",
"file_extension" -> ".wl",
"mimetype" -> "text/x-mathematica",
"name" -> "WolframScript",
"nbformat" -> 4,
"nbformat_minor" -> 2
&,
nb = NotebookImport[# _,"FlattenCellGroups" -> False]~
DeleteCases~ HoldComplete[Null],
Export[[email protected]#<>".ipynb", [email protected], "JSON"]
]&
No lo he probado con el kernel oficial de WRI, pero supongo que simplemente necesitas modificar el metadata
campo.