mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-10-06 19:46:00 +08:00
Add support for exporting JS output (#826)
This commit is contained in:
parent
fc3fad6543
commit
8622ae2ec3
2 changed files with 153 additions and 33 deletions
|
@ -144,8 +144,24 @@ defmodule Livebook.LiveMarkdown.Export do
|
||||||
["```", "vega-lite\n", Jason.encode!(spec), "\n", "```"]
|
["```", "vega-lite\n", Jason.encode!(spec), "\n", "```"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp render_output({:js_static, %{export: %{info_string: info_string, key: key}}, data})
|
||||||
|
when is_binary(info_string) do
|
||||||
|
payload = if key && is_map(data), do: data[key], else: data
|
||||||
|
|
||||||
|
case encode_js_data(payload) do
|
||||||
|
{:ok, binary} ->
|
||||||
|
["```", info_string, "\n", binary, "\n", "```"]
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
:ignored
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp render_output(_output), do: :ignored
|
defp render_output(_output), do: :ignored
|
||||||
|
|
||||||
|
defp encode_js_data(data) when is_binary(data), do: {:ok, data}
|
||||||
|
defp encode_js_data(data), do: Jason.encode(data)
|
||||||
|
|
||||||
defp get_elixir_cell_code(%{source: source, disable_formatting: true}),
|
defp get_elixir_cell_code(%{source: source, disable_formatting: true}),
|
||||||
do: source
|
do: source
|
||||||
|
|
||||||
|
|
|
@ -678,7 +678,7 @@ defmodule Livebook.LiveMarkdown.ExportTest do
|
||||||
assert expected_document == document
|
assert expected_document == document
|
||||||
end
|
end
|
||||||
|
|
||||||
test "includes vega_lite_static output" do
|
test "does not include js_static output with no export info" do
|
||||||
notebook = %{
|
notebook = %{
|
||||||
Notebook.new()
|
Notebook.new()
|
||||||
| name: "My Notebook",
|
| name: "My Notebook",
|
||||||
|
@ -689,34 +689,13 @@ defmodule Livebook.LiveMarkdown.ExportTest do
|
||||||
cells: [
|
cells: [
|
||||||
%{
|
%{
|
||||||
Notebook.Cell.new(:elixir)
|
Notebook.Cell.new(:elixir)
|
||||||
| source: """
|
| source: ":ok",
|
||||||
Vl.new(width: 500, height: 200)
|
|
||||||
|> Vl.data_from_series(in: [1, 2, 3, 4, 5], out: [1, 2, 3, 4, 5])
|
|
||||||
|> Vl.mark(:line)
|
|
||||||
|> Vl.encode_field(:x, "in", type: :quantitative)
|
|
||||||
|> Vl.encode_field(:y, "out", type: :quantitative)\
|
|
||||||
""",
|
|
||||||
outputs: [
|
outputs: [
|
||||||
{:vega_lite_static,
|
{:js_static,
|
||||||
%{
|
%{
|
||||||
"$schema" => "https://vega.github.io/schema/vega-lite/v5.json",
|
assets: %{archive_path: "", hash: "abcd", js_path: "main.js"},
|
||||||
"data" => %{
|
export: nil
|
||||||
"values" => [
|
}, "data"}
|
||||||
%{"in" => 1, "out" => 1},
|
|
||||||
%{"in" => 2, "out" => 2},
|
|
||||||
%{"in" => 3, "out" => 3},
|
|
||||||
%{"in" => 4, "out" => 4},
|
|
||||||
%{"in" => 5, "out" => 5}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"encoding" => %{
|
|
||||||
"x" => %{"field" => "in", "type" => "quantitative"},
|
|
||||||
"y" => %{"field" => "out", "type" => "quantitative"}
|
|
||||||
},
|
|
||||||
"height" => 200,
|
|
||||||
"mark" => "line",
|
|
||||||
"width" => 500
|
|
||||||
}}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -730,15 +709,140 @@ defmodule Livebook.LiveMarkdown.ExportTest do
|
||||||
## Section 1
|
## Section 1
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
Vl.new(width: 500, height: 200)
|
:ok
|
||||||
|> Vl.data_from_series(in: [1, 2, 3, 4, 5], out: [1, 2, 3, 4, 5])
|
```
|
||||||
|> Vl.mark(:line)
|
"""
|
||||||
|> Vl.encode_field(:x, "in", type: :quantitative)
|
|
||||||
|> Vl.encode_field(:y, "out", type: :quantitative)
|
document = Export.notebook_to_markdown(notebook, include_outputs: true)
|
||||||
|
|
||||||
|
assert expected_document == document
|
||||||
|
end
|
||||||
|
|
||||||
|
test "includes js_static output if export info is set" do
|
||||||
|
notebook = %{
|
||||||
|
Notebook.new()
|
||||||
|
| name: "My Notebook",
|
||||||
|
sections: [
|
||||||
|
%{
|
||||||
|
Notebook.Section.new()
|
||||||
|
| name: "Section 1",
|
||||||
|
cells: [
|
||||||
|
%{
|
||||||
|
Notebook.Cell.new(:elixir)
|
||||||
|
| source: ":ok",
|
||||||
|
outputs: [
|
||||||
|
{:js_static,
|
||||||
|
%{
|
||||||
|
assets: %{archive_path: "", hash: "abcd", js_path: "main.js"},
|
||||||
|
export: %{info_string: "mermaid", key: nil}
|
||||||
|
}, "graph TD;\nA-->B;"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
expected_document = """
|
||||||
|
# My Notebook
|
||||||
|
|
||||||
|
## Section 1
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
:ok
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD;
|
||||||
|
A-->B;
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
document = Export.notebook_to_markdown(notebook, include_outputs: true)
|
||||||
|
|
||||||
|
assert expected_document == document
|
||||||
|
end
|
||||||
|
|
||||||
|
test "serializes js_static data to JSON if not binary" do
|
||||||
|
notebook = %{
|
||||||
|
Notebook.new()
|
||||||
|
| name: "My Notebook",
|
||||||
|
sections: [
|
||||||
|
%{
|
||||||
|
Notebook.Section.new()
|
||||||
|
| name: "Section 1",
|
||||||
|
cells: [
|
||||||
|
%{
|
||||||
|
Notebook.Cell.new(:elixir)
|
||||||
|
| source: ":ok",
|
||||||
|
outputs: [
|
||||||
|
{:js_static,
|
||||||
|
%{
|
||||||
|
assets: %{archive_path: "", hash: "abcd", js_path: "main.js"},
|
||||||
|
export: %{info_string: "box", key: nil}
|
||||||
|
}, %{height: 50, width: 50}}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
expected_document = """
|
||||||
|
# My Notebook
|
||||||
|
|
||||||
|
## Section 1
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
:ok
|
||||||
|
```
|
||||||
|
|
||||||
|
```box
|
||||||
|
{"height":50,"width":50}
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
document = Export.notebook_to_markdown(notebook, include_outputs: true)
|
||||||
|
|
||||||
|
assert expected_document == document
|
||||||
|
end
|
||||||
|
|
||||||
|
test "exports partial js_static data when export_key is set" do
|
||||||
|
notebook = %{
|
||||||
|
Notebook.new()
|
||||||
|
| name: "My Notebook",
|
||||||
|
sections: [
|
||||||
|
%{
|
||||||
|
Notebook.Section.new()
|
||||||
|
| name: "Section 1",
|
||||||
|
cells: [
|
||||||
|
%{
|
||||||
|
Notebook.Cell.new(:elixir)
|
||||||
|
| source: ":ok",
|
||||||
|
outputs: [
|
||||||
|
{:js_static,
|
||||||
|
%{
|
||||||
|
assets: %{archive_path: "", hash: "abcd", js_path: "main.js"},
|
||||||
|
export: %{info_string: "vega-lite", key: :spec}
|
||||||
|
}, %{spec: %{"height" => 50, "width" => 50}, datasets: []}}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
expected_document = """
|
||||||
|
# My Notebook
|
||||||
|
|
||||||
|
## Section 1
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
:ok
|
||||||
```
|
```
|
||||||
|
|
||||||
```vega-lite
|
```vega-lite
|
||||||
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"in":1,"out":1},{"in":2,"out":2},{"in":3,"out":3},{"in":4,"out":4},{"in":5,"out":5}]},"encoding":{"x":{"field":"in","type":"quantitative"},"y":{"field":"out","type":"quantitative"}},"height":200,"mark":"line","width":500}
|
{"height":50,"width":50}
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue