Merge branch 'master' into feature/README-md-cleanup

This commit is contained in:
cc-wr 2020-02-07 06:35:30 -05:00 committed by GitHub
commit ab6ab8a2e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 195 additions and 56 deletions

View File

@ -6,7 +6,7 @@
Paclet[
Name -> "WolframLanguageForJupyter",
Version -> "0.9.1",
Version -> "0.9.2",
MathematicaVersion -> "11.2+",
Extensions -> {
{"Kernel", Context -> {"WolframLanguageForJupyter`"}},

View File

@ -71,8 +71,9 @@ If[
sends output to Jupyter
*************************************)
(* redirect Print calls into a message to Jupyter, in order to print in the Jupyter notebook *)
(* redirect Print calls into a message to Jupyter, in order to print in Jupyter *)
(* TODO: review other methods: through EvaluationData or WSTP so we don't redefine Print *)
(* TODO: remove this and just permanently set $Output to {..., loopState["WolframLanguageForJupyter-stdout"], ...} *)
Unprotect[Print];
Print[ourArgs___, opts:OptionsPattern[]] :=
Block[
@ -95,6 +96,76 @@ If[
] /; !TrueQ[$inPrint];
Protect[Print];
(************************************
version of Write that
sends output to Jupyter
*************************************)
(* redirect Write["stdout", ourArgs___] calls to Write[loopState["WolframLanguageForJupyter-stdout"], ourArgs___],
in order to print in Jupyter *)
Unprotect[Write];
Write["stdout", ourArgs___, opts:OptionsPattern[]] :=
Block[
{
$inWrite = True
},
If[
loopState["WolframLanguageForJupyter-stdout"] =!= False,
Write[loopState["WolframLanguageForJupyter-stdout"], ourArgs]
];
] /; !TrueQ[$inWrite];
Protect[Write];
(* redirect Write[{before___, "stdout", after___}, ourArgs___] calls to
Write[{before___, "WolframLanguageForJupyter-stdout", after___}, ourArgs___],
in order to print in Jupyter *)
Unprotect[Write];
Write[{before___, "stdout", after___}, ourArgs___, opts:OptionsPattern[]] :=
Block[
{
$inWrite = True
},
If[
loopState["WolframLanguageForJupyter-stdout"] =!= False,
Write[{before, loopState["WolframLanguageForJupyter-stdout"], after}, ourArgs]
];
] /; !TrueQ[$inWrite];
Protect[Write];
(************************************
version of WriteString that
sends output to Jupyter
*************************************)
(* redirect WriteString["stdout", ourArgs___] calls to WriteString[loopState["WolframLanguageForJupyter-stdout"], ourArgs___],
in order to print in Jupyter *)
Unprotect[WriteString];
WriteString["stdout", ourArgs___, opts:OptionsPattern[]] :=
Block[
{
$inWriteString = True
},
If[
loopState["WolframLanguageForJupyter-stdout"] =!= False,
WriteString[loopState["WolframLanguageForJupyter-stdout"], ourArgs]
];
] /; !TrueQ[$inWriteString];
Protect[WriteString];
(* redirect WriteString[{before___, "stdout", after___}, ourArgs___] calls to
WriteString[{before___, "WolframLanguageForJupyter-stdout", after___}, ourArgs___],
in order to print in Jupyter *)
Unprotect[WriteString];
WriteString[{before___, "stdout", after___}, ourArgs___, opts:OptionsPattern[]] :=
Block[
{
$inWriteString = True
},
If[
loopState["WolframLanguageForJupyter-stdout"] =!= False,
WriteString[{before, loopState["WolframLanguageForJupyter-stdout"], after}, ourArgs]
];
] /; !TrueQ[$inWriteString];
Protect[WriteString];
(************************************
versions of Quit and Exit that
ask the Jupyter console

View File

@ -5,12 +5,14 @@ Description:
Initialization for
WolframLanguageForJupyter
Symbols defined:
$defaultPageWidth,
loopState,
applyHook,
$canUseFrontEnd,
$outputSetToTraditionalForm,
$outputSetToTeXForm,
$trueFormatType,
$truePageWidth,
connectionAssoc,
bannerWarning,
keyString,
@ -57,7 +59,8 @@ If[
*************************************)
(* make Short[] work *)
SetOptions[$Output, PageWidth -> 89];
$defaultPageWidth = 89;
SetOptions[$Output, PageWidth -> $defaultPageWidth];
(* do not output messages to the jupyter notebook invocation
$Messages = {};
@ -192,6 +195,9 @@ If[
(* flag for if an is_complete_request has ever been sent to the kernel *)
"isCompleteRequestSent" -> False,
(* OutputStream for Jupyter's stdout *)
"WolframLanguageForJupyter-stdout" -> False,
(* local to an iteration *)
(* a received frame as an Association *)
"frameAssoc" -> Null,
@ -224,6 +230,14 @@ If[
TraditionalForm,
If[$outputSetToTeXForm, TeXForm, #&]
];
$truePageWidth :=
Replace[
Lookup[Options[$Output], PageWidth],
Except[
pageWidth_ /; ((IntegerQ[pageWidth]) && (pageWidth > 0))
] ->
$defaultPageWidth
];
(* hard-coded base64 rasterization of $Failed *)
failedInBase64 = "iVBORw0KGgoAAAANSUhEUgAAADcAAAARCAIAAAD2TKM6AAAAhXpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjaVYvBDcMwDAP/mqIjyLJM2uMYiQNkg45fuu0n9yApgbT1vi97felp2dgxABc5csRU6P6juNciDXn+X9MfZGWgoRhTluEkhnJXkqKFN+LCAahYcIbnIV8gNQN3o86928QyPusLVffpbh/5eCey76LuBgAAAAlwSFlzAAALEwAACxMBAJqcGAAAADx0RVh0U29mdHdhcmUAQ3JlYXRlZCB3aXRoIHRoZSBXb2xmcmFtIExhbmd1YWdlIDogd3d3LndvbGZyYW0uY29tXKKmhQAAACF0RVh0Q3JlYXRpb24gVGltZQAyMDE5OjA3OjAyIDAzOjExOjExSFD8JQAAA8xJREFUSInVlk9IKl8Ux68ajjThLynMwCKLICSDjBbRxpVSFhFkCtFfBMMKAhcu3GXhQopaJBEFISjhsn9YUGE6zSJqkRURFVpKLQqNcYgZHectpszfez9exoP33u+zmnPm3HO/c865w2XRNA3+eth/WkBOfKjEMAzH8T8o5Sd8qJybm1tcXPz1jCaTyeVyMc8URXV3d2s0Go1GEwgEvppqZGQERdEPldfX1yiKIghydnaWCerp6WFn0dbW9mlekiTdbrfX62VMNpvd398/MDAQCATu7u6+qnJ9fT0SiQAA8gAAJycnzc3NnZ2dfD5foVA4nc7W1lYAQDqd1uv1drudWZOXl/dpXi6XG4lEOBwOY7JYLLVaDQDIz8//qsRs2AAAt9vd2NjodrsXFhYuLy9VKlXmNQRB/7wDwzAAIBaLmc1miUTC5/MHBwfPz8+ZSJvNJpVKpVKpTCazWq2fbkySpMViEYvFAoFAp9M9Pz8z/v39/bq6Oj6fr9FoMueEDQBQKpUoihqNxtvb2+Li4kwlAADxePz6nXQ6DQC4uroKBoPz8/MoimIYZjabmciuri6Hw+FwOMRi8ePj46cqLRaLx+NZXV1dW1u7v78fGxsDAESj0fb29qamJp/PV19f//Ly8hZN0zRN016vVy6Xs9nsoaGh19dXxqnT6QAAzFByOJxYLEa/Q5Lk6enp9PQ0BEE4jtNZ9Pb2Go1G+t9UVla6XK6MmUwmIQja3t5mzI2NjYKCApqm7Xa7RCJJpVKMv6yszOPx0DT9dnpUKtXx8fHW1tbm5ubk5GTmi0dHRymKoigqlUoVFhYCAAiCMBqNQqFweHj48PCQIIh4PP5p5b4jHA4TBNHS0sLlcrlcbkdHB0EQOI7f3NzU1tZmN/Oj4wcHBxiGMVpVKlVm1P6TqakpBEEuLi4QBJmdnc1RFovFoigqY4pEIhaL5ff7SZIkSTKVSpEkCcOwQCAIBoM/LmcDACYmJqqrq/v6+rRarcfjYRr9kzJUVVWJRKJEImGz2XJU2dDQsLu7m06nHx4eAAAwDKvVapPJxExwNBpFEAQAoFAoQqHQ0tISSZIrKytM8JvKnZ0dxoVhmM/n02q1mQL8uJ/BYPD7/UKhsKKioqioCIKgXFTq9fq9vT0YhuVyOVPU5eXlkpKS8vLy0tJSqVTK/POVSuX4+LjBYODxeE6ns6am5m19ZqKtVuvMzAydAwRBhEIhiqJyCc5AUVQoFEomk9lOHMfD4fB3qRKJxNPTU7aHRb/fiY6Ojng8nkwmy7GJv5MPlX8z/4+b2zdkknhkRbjZsAAAAABJRU5ErkJggg==";
@ -252,6 +266,44 @@ If[
inputString = StringJoin[baseString, connectionAssoc["stdin_port"]];
shellString = StringJoin[baseString, connectionAssoc["shell_port"]];
Block[
{
(* for storing the result of defining a new OutputStream method *)
customOutputStreamMethod
},
(* define an OutputStream method that will allow writing to Jupyter's stdout *)
customOutputStreamMethod =
DefineOutputStreamMethod[
"for-WolframLanguageForJupyter-stdout",
{
"ConstructorFunction" -> Function[{name, isAppend, caller, opts}, {True, {}}],
"WriteFunction" ->
Function[
{state, bytes},
If[
loopState["frameAssoc"] =!= Null,
redirectPrint[loopState["frameAssoc"], FromCharacterCode[bytes]];
];
{Length[bytes], {}}
]
}
];
(* if defining a new OutputStream method did not fail,
open an OutputStream using the new method, and store it in loopState *)
If[
!FailureQ[customOutputStreamMethod],
loopState["WolframLanguageForJupyter-stdout"] =
OpenWrite["WolframLanguageForJupyter-stdout", Method -> "for-WolframLanguageForJupyter-stdout"];
(* -- also, if opening the OutputStream failed, reset loopState["WolframLanguageForJupyter-stdout"] back to False *)
If[
FailureQ[loopState["WolframLanguageForJupyter-stdout"]],
loopState["WolframLanguageForJupyter-stdout"] = False;
];
];
];
(************************************
open all the non-heartbeat
sockets

View File

@ -108,7 +108,7 @@ If[
(* the message type to be used for the reply message frame *)
replyType_String,
(* the content to be used for the reply message frame *)
replyContent_String,
replyContent : (_String | _ByteArray),
(* whether to list sourceFrame as a parent for the reply message frame *)
branchOff:(True|False)
] :=
@ -157,7 +157,7 @@ If[
result["header"],
result["pheader"],
result["metadata"],
result["content"]
If[StringQ[result["content"]], result["content"], ByteArrayToString[result["content"]]]
]
]
];

View File

@ -32,7 +32,8 @@ If[
Get[FileNameJoin[{DirectoryName[$InputFileName], "Initialization.wl"}]]; (* $canUseFrontEnd, $outputSetToTeXForm,
$outputSetToTraditionalForm,
$trueFormatType, failedInBase64 *)
$trueFormatType, $truePageWidth,
failedInBase64 *)
(************************************
private symbols
@ -182,7 +183,16 @@ If[
(* generate the textual form of a result *)
(* NOTE: the OutputForm (which ToString uses) of any expressions wrapped with, say, InputForm should
be identical to the string result of an InputForm-wrapped expression itself *)
toText[result_] := ToString[If[Head[result] =!= TeXForm, $trueFormatType[result], result]];
toText[result_] :=
ToString[
If[
Head[result] =!= TeXForm,
$trueFormatType[result],
result
],
(* also, use the current PageWidth setting for $Output *)
PageWidth -> $truePageWidth
];
(* generate HTML for the textual form of a result *)
toOutTextHTML[result_] :=

View File

@ -283,7 +283,7 @@ If[
toOut = toOutImageHTML
];
(* prepare the content for a reply message frame to be sent on the IO Publish socket *)
ioPubReplyContent = ExportString[
ioPubReplyContent = ExportByteArray[
Association[
(* the first output index *)
"execution_count" -> First[totalResult["EvaluationResultOutputLineIndices"]],
@ -292,52 +292,58 @@ If[
{
(* generate HTML for the results and messages *)
"text/html" ->
(* output the results in a grid *)
If[
Length[totalResult["EvaluationResult"]] > 1,
StringJoin[
(* add grid style *)
"<style>
.grid-container {
display: inline-grid;
grid-template-columns: auto;
}
</style>
loopState["isCompleteRequestSent"],
(* if an is_complete_request has been sent, assume jupyter-console is running the kernel,
and do not generate HTML *)
"",
(* otherwise, output the results in a grid *)
If[
Length[totalResult["EvaluationResult"]] > 1,
StringJoin[
(* add grid style *)
"<style>
.grid-container {
display: inline-grid;
grid-template-columns: auto;
}
</style>
<div>",
(* display error message *)
errorMessage,
(* start the grid *)
"<div class=\"grid-container\">",
(* display the output lines *)
Table[
{
(* start the grid item *)
"<div class=\"grid-item\">",
(* show the output line *)
toOut[totalResult["EvaluationResult"][[outIndex]]],
(* end the grid item *)
"</div>"
},
{outIndex, 1, Length[totalResult["EvaluationResult"]]}
<div>",
(* display error message *)
errorMessage,
(* start the grid *)
"<div class=\"grid-container\">",
(* display the output lines *)
Table[
{
(* start the grid item *)
"<div class=\"grid-item\">",
(* show the output line *)
toOut[totalResult["EvaluationResult"][[outIndex]]],
(* end the grid item *)
"</div>"
},
{outIndex, 1, Length[totalResult["EvaluationResult"]]}
],
(* end the element *)
"</div></div>"
],
(* end the element *)
"</div></div>"
],
StringJoin[
(* start the element *)
"<div>",
(* display error message *)
errorMessage,
(* if there are messages, but no results, do not display a result *)
If[
Length[totalResult["EvaluationResult"]] == 0,
"",
(* otherwise, display a result *)
toOut[First[totalResult["EvaluationResult"]]]
],
(* end the element *)
"</div>"
StringJoin[
(* start the element *)
"<div>",
(* display error message *)
errorMessage,
(* if there are messages, but no results, do not display a result *)
If[
Length[totalResult["EvaluationResult"]] == 0,
"",
(* otherwise, display a result *)
toOut[First[totalResult["EvaluationResult"]]]
],
(* end the element *)
"</div>"
]
]
],
(* provide, as a backup, plain text for the results *)

View File

@ -74,7 +74,7 @@ If[
socketWriteFunction[
socket,
StringToByteArray[frame["content"]],
If[ByteArrayQ[frame["content"]], frame["content"], StringToByteArray[frame["content"]]],
"Multipart" -> False
];
];

View File

@ -139,7 +139,7 @@ splitPath :=
(* find Jupyter installation path *)
(* returns above *)
findJupyerPath[] :=
findJupyterPath[] :=
SelectFirst[
splitPath,
(* check every directory in PATH to see if a Jupyter binary is a member *)
@ -211,7 +211,7 @@ configureJupyter[specs_Association, removeQ_?BooleanQ, removeAllQ_?BooleanQ] :=
(* if no Jupyter installation path provided, determine it from PATH *)
If[
MissingQ[jupyterPath],
jupyterPath = findJupyerPath[];
jupyterPath = findJupyterPath[];
(* if Jupyter not on PATH, message *)
If[MissingQ[jupyterPath],
Message[ConfigureJupyter::notfound, "Jupyter"];

View File

@ -160,7 +160,7 @@ attemptPathRegeneration[] := If[
(* find Jupyter installation path *)
(* returns kernel IDs in Jupyter *)
findJupyerPath[] :=
findJupyterPath[] :=
SelectFirst[
splitPath,
(* check every directory in PATH to see if a Jupyter binary is a member *)
@ -231,7 +231,7 @@ configureJupyter[specs_Association, removeQ_?BooleanQ, removeAllQ_?BooleanQ] :=
(* if no Jupyter installation path provided, determine it from PATH *)
If[
MissingQ[jupyterPath],
jupyterPath = findJupyerPath[];
jupyterPath = findJupyterPath[];
(* if Jupyter not on PATH, message *)
If[MissingQ[jupyterPath],
Print[notfound];