Optimise string building with iodata (#478)

This commit is contained in:
Jonatan Kłosko 2021-07-28 14:27:11 +02:00 committed by GitHub
parent cfbba9e2ce
commit 917e59c57d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 40 deletions

View file

@ -428,8 +428,7 @@ defmodule Livebook.Intellisense do
inner
|> String.split("\n")
|> Enum.map(&("> " <> &1))
|> Enum.join("\n")
|> Enum.map_intersperse("\n", &["> ", &1])
end
defp render_unordered_list(content) do

View file

@ -14,7 +14,7 @@ defmodule Livebook.LiveMarkdown.Export do
end
defp render_notebook(notebook) do
name = "# #{notebook.name}"
name = ["# ", notebook.name]
sections = Enum.map(notebook.sections, &render_section(&1, notebook))
[name | sections]
@ -23,7 +23,7 @@ defmodule Livebook.LiveMarkdown.Export do
end
defp render_section(section, notebook) do
name = "## #{section.name}"
name = ["## ", section.name]
{cells, _} =
Enum.map_reduce(section.cells, nil, fn cell, prev_cell ->
@ -61,14 +61,10 @@ defmodule Livebook.LiveMarkdown.Export do
end
defp render_cell(%Cell.Elixir{} = cell) do
delimiter = code_block_delimiter(cell.source)
code = get_elixir_cell_code(cell)
delimiter = code_block_delimiter(code)
"""
#{delimiter}elixir
#{code}
#{delimiter}\
"""
[delimiter, "elixir\n", code, "\n", delimiter]
|> prepend_metadata(cell.metadata)
end
@ -141,9 +137,7 @@ defmodule Livebook.LiveMarkdown.Export do
defp format_code(code) do
try do
code
|> Code.format_string!()
|> IO.iodata_to_binary()
Code.format_string!(code)
rescue
_ -> code
end

View file

@ -161,38 +161,38 @@ defmodule Livebook.LiveMarkdown.MarkdownHelpers do
@void_elements ~W(area base br col command embed hr img input keygen link meta param source track wbr)
defp render_html(tag, attrs, []) when tag in @void_elements do
"<#{tag} #{attrs_to_string(attrs)} />"
["<", tag, " ", attrs_to_string(attrs), " />"]
end
defp render_html(tag, attrs, lines) do
inner = Enum.join(lines, "\n")
"<#{tag} #{attrs_to_string(attrs)}>\n#{inner}\n</#{tag}>"
inner = Enum.intersperse(lines, "\n")
["<", tag, " ", attrs_to_string(attrs), ">\n", inner, "\n</", tag, ">"]
end
defp render_emphasis(content) do
inner = markdown_from_ast(content)
"*#{inner}*"
["*", inner, "*"]
end
defp render_strong(content) do
inner = markdown_from_ast(content)
"**#{inner}**"
["**", inner, "**"]
end
defp render_strikethrough(content) do
inner = markdown_from_ast(content)
"~~#{inner}~~"
["~~", inner, "~~"]
end
defp render_code_inline(content) do
inner = markdown_from_ast(content)
"`#{inner}`"
["`", inner, "`"]
end
defp render_link(content, attrs) do
caption = markdown_from_ast(content)
caption = build_md([], content)
href = get_attr(attrs, "href", "")
"[#{caption}](#{href})"
["[", caption, "](", href, ")"]
end
defp render_image(attrs) do
@ -201,15 +201,15 @@ defmodule Livebook.LiveMarkdown.MarkdownHelpers do
title = get_attr(attrs, "title", "")
if title == "" do
"![#{alt}](#{src})"
["![", alt, "](", src, ")"]
else
~s/![#{alt}](#{src} "#{title}")/
["![", alt, "](", src, ~s/ "/, title, ~s/")/]
end
end
defp render_comment([line]) do
line = String.trim(line)
"<!-- #{line} -->"
["<!-- ", line, " -->"]
end
defp render_comment(lines) do
@ -220,7 +220,7 @@ defmodule Livebook.LiveMarkdown.MarkdownHelpers do
|> Enum.drop_while(&blank?/1)
|> Enum.reverse()
Enum.join(["<!--" | lines] ++ ["-->"], "\n")
["<!--\n", Enum.intersperse(lines, "\n"), "\n-->"]
end
defp render_ruler(attrs) do
@ -238,13 +238,13 @@ defmodule Livebook.LiveMarkdown.MarkdownHelpers do
defp render_paragraph(content), do: markdown_from_ast(content)
defp render_heading(n, content) do
title = markdown_from_ast(content)
String.duplicate("#", n) <> " " <> title
title = build_md([], content)
[String.duplicate("#", n), " ", title]
end
defp render_code_block(content, attrs) do
language = get_attr(attrs, "class", "")
"```#{language}\n#{content}\n```"
["```", language, "\n", content, "\n```"]
end
defp render_blockquote(content) do
@ -252,8 +252,7 @@ defmodule Livebook.LiveMarkdown.MarkdownHelpers do
inner
|> String.split("\n")
|> Enum.map(&("> " <> &1))
|> Enum.join("\n")
|> Enum.map_intersperse("\n", &["> ", &1])
end
defp render_table([{"thead", _, [head_row], %{}}, {"tbody", _, body_rows, %{}}]) do
@ -275,7 +274,7 @@ defmodule Livebook.LiveMarkdown.MarkdownHelpers do
defp cell_grid_from_rows(rows) do
Enum.map(rows, fn {"tr", _, columns, %{}} ->
Enum.map(columns, fn {tag, _, content, %{}} when tag in ["th", "td"] ->
markdown_from_ast(content)
build_md([], content)
end)
end)
end
@ -308,7 +307,7 @@ defmodule Livebook.LiveMarkdown.MarkdownHelpers do
|> Enum.map(&Tuple.to_list/1)
|> Enum.map(fn cells ->
cells
|> Enum.map(&String.length/1)
|> Enum.map(&IO.iodata_length/1)
|> Enum.max()
end)
end
@ -317,16 +316,18 @@ defmodule Livebook.LiveMarkdown.MarkdownHelpers do
cells
|> Enum.zip(widths)
|> Enum.map(fn {cell, width} ->
String.pad_trailing(cell, width, " ")
length = IO.iodata_length(cell)
missing = max(width - length, 0)
[cell, String.duplicate(" ", missing)]
end)
end
defp cell_grid_to_md_table(cell_grid) do
cell_grid
|> Enum.map(fn cells ->
"| " <> Enum.join(cells, " | ") <> " |"
["| ", Enum.intersperse(cells, " | "), " |"]
end)
|> Enum.join("\n")
|> Enum.intersperse("\n")
end
defp render_unordered_list(content) do
@ -349,17 +350,17 @@ defmodule Livebook.LiveMarkdown.MarkdownHelpers do
|> Enum.map(fn {inner, index} ->
[first_line | lines] = String.split(inner, "\n")
first_line = marker_fun.(index) <> first_line
first_line = [marker_fun.(index), first_line]
lines =
Enum.map(lines, fn
"" -> ""
line -> indent <> line
line -> [indent, line]
end)
Enum.join([first_line | lines], "\n")
Enum.intersperse([first_line | lines], "\n")
end)
|> Enum.join(item_separator)
|> Enum.intersperse(item_separator)
end
defp spaced_list_items?([{"li", _, [{"p", _, _content, %{}} | _], %{}} | _items]), do: true