Redirect all string references to the stdout stream to a new WolframLanguageForJupyter-stdout stream

This commit is contained in:
cc-wr 2020-01-16 06:02:42 -05:00
parent 3523e815e6
commit 570eab43eb
2 changed files with 112 additions and 1 deletions

View File

@ -66,12 +66,82 @@ If[
uninteract[expr_] := UsingFrontEnd[applyHook[$Pre, expr]];
SetAttributes[uninteract, HoldAll];
(************************************
version of Write that
sends output to Jupyter
*************************************)
(* redirect Write["stdout", ourArgs___] calls to Write[loopState["WolframLanguageForJupyter-stdout"], ourArgs___],
in order to print in the 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 the 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 the 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 the 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];
(************************************
version of Print that
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 *)
Unprotect[Print];
Print[ourArgs___, opts:OptionsPattern[]] :=

View File

@ -192,6 +192,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,
@ -252,6 +255,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