Packages
livebook
0.3.2
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook_web/live/output.ex
defmodule LivebookWeb.Output do
use Phoenix.Component
@doc """
Renders the given cell output.
"""
@spec render_output(Livebook.Cell.Elixir.output(), %{
id: String.t(),
socket: Phoenix.LiveView.Socket.t(),
runtime: Livebook.Runtime.t()
}) :: Phoenix.LiveView.Rendered.t()
def render_output(output, context)
def render_output(text, %{id: id}) when is_binary(text) do
# Captured output usually has a trailing newline that we can ignore,
# because each line is itself an HTML block anyway.
text = String.replace_suffix(text, "\n", "")
live_component(LivebookWeb.Output.TextComponent, id: id, content: text, follow: true)
end
def render_output({:text, text}, %{id: id}) do
live_component(LivebookWeb.Output.TextComponent, id: id, content: text, follow: false)
end
def render_output({:markdown, markdown}, %{id: id}) do
live_component(LivebookWeb.Output.MarkdownComponent, id: id, content: markdown)
end
def render_output({:image, content, mime_type}, %{id: id}) do
live_component(LivebookWeb.Output.ImageComponent,
id: id,
content: content,
mime_type: mime_type
)
end
def render_output({:vega_lite_static, spec}, %{id: id}) do
live_component(LivebookWeb.Output.VegaLiteStaticComponent, id: id, spec: spec)
end
def render_output({:vega_lite_dynamic, pid}, %{id: id, socket: socket}) do
live_render(socket, LivebookWeb.Output.VegaLiteDynamicLive,
id: id,
session: %{"id" => id, "pid" => pid}
)
end
def render_output({:table_dynamic, pid}, %{id: id, socket: socket}) do
live_render(socket, LivebookWeb.Output.TableDynamicLive,
id: id,
session: %{"id" => id, "pid" => pid}
)
end
def render_output({:frame_dynamic, pid}, %{id: id, socket: socket}) do
live_render(socket, LivebookWeb.Output.FrameDynamicLive,
id: id,
session: %{"id" => id, "pid" => pid}
)
end
def render_output({:error, formatted, :runtime_restart_required}, %{runtime: runtime})
when runtime != nil do
assigns = %{formatted: formatted, is_standalone: Livebook.Runtime.standalone?(runtime)}
~H"""
<div class="flex flex-col space-y-4">
<%= render_error_message_output(@formatted) %>
<%= if @is_standalone do %>
<div>
<button class="button button-gray" phx-click="restart_runtime">
Restart runtime
</button>
</div>
<% else %>
<div class="text-red-600">
<span class="font-semibold">Note:</span>
This operation requires restarting the runtime, but we cannot
do it automatically for the current runtime
</div>
<% end %>
</div>
"""
end
def render_output({:error, formatted, _type}, %{}) do
render_error_message_output(formatted)
end
def render_output(output, %{}) do
render_error_message_output("""
Unknown output format: #{inspect(output)}. If you're using Kino,
you may want to update Kino and Livebook to the latest version.
""")
end
defp render_error_message_output(message) do
assigns = %{message: message}
~H"""
<div class="overflow-auto whitespace-pre text-red-600 tiny-scrollbar"><%= @message %></div>
"""
end
end