sloane.sh/lib/sloane_sh/markdown.ex

54 lines
1.1 KiB
Elixir

defmodule SloaneSH.Markdown do
@moduledoc """
Markdown parsing using `Earmark` and `Earmark.Parser`
"""
require Logger
use TypedStruct
alias SloaneSH.Context
alias __MODULE__
typedstruct do
field :attrs, map(), default: %{}
field :html, String.t(), default: ""
end
def transform(%Context{} = ctx, data) when is_binary(data) do
data
|> parse_attrs(ctx)
|> parse_markdown(ctx)
end
defp parse_attrs("+++" <> rest, _ctx) do
[toml, body] = String.split(rest, ["+++\n", "+++\r\n"], parts: 2)
with {:ok, attrs} <- Toml.decode(toml, keys: :atoms) do
{:ok, attrs, body}
end
end
defp parse_attrs(body, _ctx) do
{:ok, %{}, body}
end
defp parse_markdown({:ok, attrs, body}, _ctx) do
with {:ok, html, msgs} <- Earmark.as_html(body) do
for msg <- msgs, do: Logger.warning(msg)
{:ok,
%Markdown{
attrs: attrs,
html: html
}}
else
{:error, _, msgs} ->
for msg <- msgs, do: Logger.error(msg)
:error
_ ->
:error
end
end
defp parse_markdown(other, _ctx), do: other
end