2024-02-16 22:28:13 -05:00
|
|
|
defmodule SloaneSH.Markdown do
|
|
|
|
@moduledoc """
|
|
|
|
Markdown parsing using `Earmark` and `Earmark.Parser`
|
|
|
|
"""
|
|
|
|
require Logger
|
2024-02-23 22:15:36 -05:00
|
|
|
use TypedStruct
|
2024-02-16 22:28:13 -05:00
|
|
|
|
|
|
|
alias SloaneSH.Context
|
2024-02-23 22:15:36 -05:00
|
|
|
alias __MODULE__
|
2024-02-16 22:28:13 -05:00
|
|
|
|
2024-02-23 22:15:36 -05:00
|
|
|
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
|
2024-02-16 22:28:13 -05:00
|
|
|
|
2024-02-23 22:15:36 -05:00
|
|
|
defp parse_attrs("+++" <> rest, _ctx) do
|
|
|
|
[toml, body] = String.split(rest, ["+++\n", "+++\r\n"], parts: 2)
|
2024-02-16 22:28:13 -05:00
|
|
|
|
2024-02-23 22:15:36 -05:00
|
|
|
with {:ok, attrs} <- Toml.decode(toml, keys: :atoms) do
|
|
|
|
{:ok, attrs, body}
|
2024-02-16 22:28:13 -05:00
|
|
|
end
|
|
|
|
end
|
2024-02-23 22:15:36 -05:00
|
|
|
|
|
|
|
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
|
2024-02-16 22:28:13 -05:00
|
|
|
end
|