defmodule Gemtext.Renderer do
@moduledoc """
Gemtext renderer
"""
require Logger
@type gemtext_blocks :: Gemtext.Parser.gemtext_blocks()
@doc ~S'''
Renders a list of gemtext blocks to string
## Examples
iex> Gemtext.Renderer.render([
...> {:h1, "Heading 1"},
...> {:text, ""},
...> {:text, "This is a robot emoji 🤖"},
...> {:text, ""},
...> {:link, %{to: "/link"}, nil},
...> ])
"# Heading 1\n\nThis is a robot emoji 🤖\n\n=> /link"
'''
def render(items) when is_list(items) do
items
|> Enum.map_join("\n", &render_item/1)
end
defp render_item({:text, body}), do: body
defp render_item({:h1, body}), do: "# #{body}"
defp render_item({:h2, body}), do: "## #{body}"
defp render_item({:h3, body}), do: "### #{body}"
defp render_item({:li, body}), do: "* #{body}"
defp render_item({:quote, body}), do: "> #{body}"
defp render_item({:link, %{to: to}, nil}), do: "=> #{to}"
defp render_item({:link, %{to: to}, body}), do: "=> #{to} #{body}"
defp render_item({:pre, %{title: title}, body}), do: "``` #{title}\n#{body}```"
defp render_item({:pre, body}), do: "```\n#{body}```"
@spec render_item(gemtext_blocks()) :: String.t()
defp render_item(item) do
Logger.warn("invalid item #{inspect(item)}")
[]
end
end