Skip to content

Commit c4ddb87

Browse files
committed
Supports inline PNG images by sending an appropriate display_data (a) output as base64 encoded, or (b) file based.
1 parent d0b91ca commit c4ddb87

File tree

6 files changed

+184
-2
lines changed

6 files changed

+184
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ iex> Number.Currency.number_to_currency(2034.46)
146146
Additional resources:
147147
* [Notebook with Boyle examples](https://github.com/pprzetacznik/IElixir/blob/master/resources/boyle%20example.ipynb)
148148
* [Notebook with Boyle examples with usage of Matrex library](https://github.com/pprzetacznik/IElixir/blob/master/resources/boyle%20example%20-%20matrex%20installation%20and%20usage.ipynb)
149+
* [Notebook with inline image examples with usage of Gnuplot library](https://github.com/pprzetacznik/IElixir/blob/master/resources/inlineplot%20example%20-%20gnuplot.ipynb)
149150

150151
### Developement mode
151152

lib/ielixir/sandbox.ex

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ defmodule IElixir.Sandbox do
88
@typedoc "Execution response"
99
@type execution_response :: {
1010
status :: :ok,
11-
result :: :"this is raw html" | :"do not show this result in output" | String.t,
11+
result :: :"this is raw html" | :"do not show this result in output" | :"this is an inline image" | {:"this is an inline image",Keyword.t} | String.t,
1212
stdout :: String.t,
1313
stderr :: String.t,
1414
execution_count :: integer}
@@ -168,6 +168,10 @@ defmodule IElixir.Sandbox do
168168
binding = case result do
169169
:"do not show this result in output" ->
170170
binding
171+
:"this is an inline image" ->
172+
binding
173+
{:"this is an inline image",_} ->
174+
binding
171175
_ ->
172176
binding
173177
|> Keyword.put(:ans, result)
@@ -220,6 +224,12 @@ defmodule IElixir.Sandbox do
220224
defp maybe_inspect(result) when result in [:"this is raw html", :"do not show this result in output"] do
221225
""
222226
end
227+
defp maybe_inspect(result = {:"this is an inline image",_}) do
228+
result
229+
end
230+
defp maybe_inspect(result = :"this is an inline image") do
231+
result
232+
end
223233
defp maybe_inspect(result) do
224234
inspect(result)
225235
end

lib/ielixir/socket/iopub.ex

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ defmodule IElixir.Socket.IOPub do
5858
GenServer.cast(IOPub, {:send_html, message, text})
5959
end
6060

61+
@doc """
62+
Send stream message but with a mime type of IMAGE, so the content
63+
is interpolated into the result
64+
"""
65+
def send_image(message, execution_count, image) do
66+
GenServer.cast(IOPub, {:send_image, message, execution_count, image})
67+
end
68+
6169
@doc """
6270
Send error message. Send traceback so client can have information about what
6371
went wrong.
@@ -98,6 +106,31 @@ defmodule IElixir.Socket.IOPub do
98106
Message.send_message(sock, message, "display_data", content)
99107
{:noreply, sock}
100108
end
109+
def handle_cast({:send_image, message, execution_count, {:file,kw}}, sock) do
110+
try do
111+
raw64 = File.read!(kw[:src]) |> Base.encode64
112+
content = %{
113+
data: %{
114+
"image/png" => raw64,
115+
},
116+
}
117+
Message.send_message(sock, message, "display_data", content)
118+
{:noreply, sock}
119+
rescue
120+
error ->
121+
traceback = System.stacktrace() |> Enum.map(&"#{inspect &1}")
122+
handle_cast({:send_error,message,execution_count,IO.inspect(error),traceback}, sock)
123+
end
124+
end
125+
def handle_cast({:send_image, message, _execution_count, {:raw,raw64}}, sock) do
126+
content = %{
127+
data: %{
128+
"image/png" => raw64,
129+
},
130+
}
131+
Message.send_message(sock, message, "display_data", content)
132+
{:noreply, sock}
133+
end
101134

102135
def handle_cast({:send_execute_result, message, {text, execution_count}}, sock) do
103136
content = %{

lib/ielixir/socket/shell.ex

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ defmodule IElixir.Socket.Shell do
158158
IOPub.send_html(response.message, response.output)
159159
response
160160
end
161+
defp publish_output(response = %{result: {:"this is an inline image",_}}) do
162+
response
163+
end
164+
defp publish_output(response = %{result: :"this is an inline image"}) do
165+
IOPub.send_image(response.message, response.count, {:raw, response.output})
166+
response
167+
end
161168
defp publish_output(response) do
162169
IOPub.send_stream(response.message, response.output)
163170
response
@@ -184,6 +191,13 @@ defmodule IElixir.Socket.Shell do
184191
defp publish_execute_response(response = %{result: :"this is raw html"}) do
185192
response
186193
end
194+
defp publish_execute_response(response = %{result: {:"this is an inline image",kw}}) do
195+
IOPub.send_image(response.message, response.count, {:file, kw})
196+
response
197+
end
198+
defp publish_execute_response(response = %{result: :"this is an inline image"}) do
199+
response
200+
end
187201
defp publish_execute_response(response = %{silent: true}) do
188202
response
189203
end

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule IElixir.Mixfile do
22
use Mix.Project
33

4-
@version "0.9.15"
4+
@version "0.9.16"
55

66
def project do
77
[app: :ielixir,

0 commit comments

Comments
 (0)