mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-04 20:14:57 +08:00
Handle backticks in Elixir code when persisting Livemarkdown (#438)
* Handle backticks in Elixir code when persisting Livemarkdown * Apply suggestions from code review Co-authored-by: José Valim <jose.valim@dashbit.co> Co-authored-by: José Valim <jose.valim@dashbit.co>
This commit is contained in:
parent
6ec263ce7c
commit
73845e4f6a
3 changed files with 70 additions and 5 deletions
|
@ -39,11 +39,12 @@ defmodule Livebook.LiveMarkdown.Export do
|
||||||
|
|
||||||
defp render_cell(%Cell.Elixir{} = cell) do
|
defp render_cell(%Cell.Elixir{} = cell) do
|
||||||
code = get_elixir_cell_code(cell)
|
code = get_elixir_cell_code(cell)
|
||||||
|
delimiter = code_block_delimiter(code)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
```elixir
|
#{delimiter}elixir
|
||||||
#{code}
|
#{code}
|
||||||
```\
|
#{delimiter}\
|
||||||
"""
|
"""
|
||||||
|> prepend_metadata(cell.metadata)
|
|> prepend_metadata(cell.metadata)
|
||||||
end
|
end
|
||||||
|
@ -117,12 +118,23 @@ defmodule Livebook.LiveMarkdown.Export do
|
||||||
|
|
||||||
defp format_code(code) do
|
defp format_code(code) do
|
||||||
try do
|
try do
|
||||||
Code.format_string!(code)
|
code
|
||||||
|
|> Code.format_string!()
|
||||||
|
|> IO.iodata_to_binary()
|
||||||
rescue
|
rescue
|
||||||
_ -> code
|
_ -> code
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp code_block_delimiter(code) do
|
||||||
|
max_streak =
|
||||||
|
Regex.scan(~r/`{3,}/, code)
|
||||||
|
|> Enum.map(fn [string] -> byte_size(string) end)
|
||||||
|
|> Enum.max(&>=/2, fn -> 2 end)
|
||||||
|
|
||||||
|
String.duplicate("`", max_streak + 1)
|
||||||
|
end
|
||||||
|
|
||||||
defp put_truthy(map, entries) do
|
defp put_truthy(map, entries) do
|
||||||
Enum.reduce(entries, map, fn {key, value}, map ->
|
Enum.reduce(entries, map, fn {key, value}, map ->
|
||||||
if value do
|
if value do
|
||||||
|
|
|
@ -154,7 +154,7 @@ most busy processes!
|
||||||
Sometimes you may want to render arbitrary content as rich-text,
|
Sometimes you may want to render arbitrary content as rich-text,
|
||||||
that's when `Kino.Markdown.new/1` comes into play:
|
that's when `Kino.Markdown.new/1` comes into play:
|
||||||
|
|
||||||
```elixir
|
````elixir
|
||||||
"""
|
"""
|
||||||
# Example
|
# Example
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ A regular Markdown file.
|
||||||
| 2 | Erlang | https://www.erlang.org |
|
| 2 | Erlang | https://www.erlang.org |
|
||||||
"""
|
"""
|
||||||
|> Kino.Markdown.new()
|
|> Kino.Markdown.new()
|
||||||
```
|
````
|
||||||
|
|
||||||
## Kino.render/1
|
## Kino.render/1
|
||||||
|
|
||||||
|
|
|
@ -418,4 +418,57 @@ defmodule Livebook.LiveMarkdown.ExportTest do
|
||||||
|
|
||||||
assert expected_document == document
|
assert expected_document == document
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "handles backticks in code cell" do
|
||||||
|
notebook = %{
|
||||||
|
Notebook.new()
|
||||||
|
| name: "My Notebook",
|
||||||
|
metadata: %{},
|
||||||
|
sections: [
|
||||||
|
%{
|
||||||
|
Notebook.Section.new()
|
||||||
|
| name: "Section 1",
|
||||||
|
metadata: %{},
|
||||||
|
cells: [
|
||||||
|
%{
|
||||||
|
Notebook.Cell.new(:elixir)
|
||||||
|
| source: """
|
||||||
|
\"\"\"
|
||||||
|
```elixir
|
||||||
|
x = 1
|
||||||
|
```
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
# Heading
|
||||||
|
````
|
||||||
|
\"\"\"\
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
expected_document = """
|
||||||
|
# My Notebook
|
||||||
|
|
||||||
|
## Section 1
|
||||||
|
|
||||||
|
`````elixir
|
||||||
|
\"\"\"
|
||||||
|
```elixir
|
||||||
|
x = 1
|
||||||
|
```
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
# Heading
|
||||||
|
````
|
||||||
|
\"\"\"
|
||||||
|
`````
|
||||||
|
"""
|
||||||
|
|
||||||
|
document = Export.notebook_to_markdown(notebook)
|
||||||
|
|
||||||
|
assert expected_document == document
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue