diff --git a/lib/livebook/notebook/app_settings.ex b/lib/livebook/notebook/app_settings.ex index a68ea7a43b0..97840b51f85 100644 --- a/lib/livebook/notebook/app_settings.ex +++ b/lib/livebook/notebook/app_settings.ex @@ -14,7 +14,8 @@ defmodule Livebook.Notebook.AppSettings do access_type: access_type(), password: String.t() | nil, show_source: boolean(), - output_type: output_type() + output_type: output_type(), + render_static: boolean() } @type access_type :: :public | :protected @@ -33,6 +34,7 @@ defmodule Livebook.Notebook.AppSettings do field :password, :string field :show_source, :boolean field :output_type, Ecto.Enum, values: [:all, :rich] + field :render_static, :boolean end @doc """ @@ -49,7 +51,8 @@ defmodule Livebook.Notebook.AppSettings do access_type: :protected, password: generate_password(), show_source: false, - output_type: :all + output_type: :all, + render_static: false } end @@ -82,14 +85,16 @@ defmodule Livebook.Notebook.AppSettings do :auto_shutdown_ms, :access_type, :show_source, - :output_type + :output_type, + :render_static ]) |> validate_required([ :slug, :multi_session, :access_type, :show_source, - :output_type + :output_type, + :render_static ]) |> validate_format(:slug, ~r/^[a-z0-9-]+$/, message: "should only contain lowercase alphanumeric characters and dashes" diff --git a/lib/livebook/notebook/cell.ex b/lib/livebook/notebook/cell.ex index 708d0a9fd22..411327fea89 100644 --- a/lib/livebook/notebook/cell.ex +++ b/lib/livebook/notebook/cell.ex @@ -49,6 +49,13 @@ defmodule Livebook.Notebook.Cell do def evaluable?(%Cell.Smart{}), do: true def evaluable?(_cell), do: false + @doc """ + Checks if the given cell can be statically rendered + """ + @spec static?(t()) :: boolean() + def static?(%Cell.Markdown{}), do: true + def static?(_), do: false + @doc """ Extracts all inputs from the given indexed output. """ diff --git a/lib/livebook_web/live/app_session_live.ex b/lib/livebook_web/live/app_session_live.ex index 45de41e213a..b1c6cc1bf9f 100644 --- a/lib/livebook_web/live/app_session_live.ex +++ b/lib/livebook_web/live/app_session_live.ex @@ -442,17 +442,42 @@ defmodule LivebookWeb.AppSessionLive do defp data_to_view(data) do changed_input_ids = Session.Data.changed_input_ids(data) - %{ - notebook_name: data.notebook.name, - cell_views: - for {cell, _section} <- Notebook.evaluable_cells_with_section(data.notebook) do + shall_render = fn cell -> + if data.notebook.app_settings.render_static do + Cell.evaluable?(cell) or Cell.static?(cell) + else + Cell.evaluable?(cell) + end + end + + cell_views = + data.notebook + |> Notebook.cells_with_section() + |> Enum.filter(fn {cell, _section} -> shall_render.(cell) end) + |> Enum.map(fn + {%Livebook.Notebook.Cell.Markdown{} = cell, _section} -> + out_id = :rand.uniform(31337) + output = {out_id, %{type: :markdown_static, text: cell.source, chunk: false}} + + %{ + id: cell.id, + input_views: [], + outputs: [output], + outputs_batch_number: 0 + } + + {cell, _section} -> %{ id: cell.id, input_views: input_views_for_cell(cell, data, changed_input_ids), outputs: filter_outputs(cell.outputs, data.notebook.app_settings.output_type), outputs_batch_number: data.cell_infos[cell.id].eval.outputs_batch_number } - end, + end) + + %{ + notebook_name: data.notebook.name, + cell_views: cell_views, app_status: data.app_data.status, show_source: data.notebook.app_settings.show_source, slug: data.notebook.app_settings.slug, diff --git a/lib/livebook_web/live/output.ex b/lib/livebook_web/live/output.ex index b7965c67d49..eb85f03928b 100644 --- a/lib/livebook_web/live/output.ex +++ b/lib/livebook_web/live/output.ex @@ -64,6 +64,19 @@ defmodule LivebookWeb.Output do """ end + defp render_output(%{type: :markdown_static} = output, %{id: id, session_id: session_id}) do + assigns = %{id: id, session_id: session_id, output: output} + + ~H""" + <.live_component + module={Output.MarkdownStaticComponent} + id={@id} + session_id={@session_id} + output={@output} + /> + """ + end + defp render_output(%{type: :image} = output, %{id: id}) do assigns = %{id: id, content: output.content, mime_type: output.mime_type} diff --git a/lib/livebook_web/live/output/markdown_static_component.ex b/lib/livebook_web/live/output/markdown_static_component.ex new file mode 100644 index 00000000000..6250d4c3d12 --- /dev/null +++ b/lib/livebook_web/live/output/markdown_static_component.ex @@ -0,0 +1,12 @@ +defmodule LivebookWeb.Output.MarkdownStaticComponent do + use LivebookWeb, :live_component + + @impl true + def render(assigns) do + ~H""" +