chiya/lib/chiya_web/markdown.ex
2023-07-05 06:49:37 +02:00

62 lines
1.5 KiB
Elixir

defmodule ChiyaWeb.Markdown do
@moduledoc """
Module used for rendering markdown.
Rendering also collects and replaces internal [references](`Mirage.References`) to other entities like Lists and Tags.
"""
import Ecto.Changeset, only: [get_change: 2, put_change: 3]
def options(),
do: %Earmark.Options{
code_class_prefix: "lang- language-",
footnotes: true,
breaks: true,
escape: false,
registered_processors: processors()
}
@doc """
Renders markdown with Earmark.
"""
def render(markdown) do
markdown
|> ChiyaWeb.References.replace_references()
|> Earmark.as_html!(options())
end
@doc """
Renders markdown to HTML inside a changeset if markdown changed.
Markdown field and HTML field can be configured.
"""
def maybe_render(changeset, markdown_field, html_field) do
if markdown = get_change(changeset, markdown_field) do
html = render(markdown)
put_change(changeset, html_field, html)
else
changeset
end
end
def processors() do
heading = fn
{_, _, [content], _} = n when is_binary(content) ->
slug = Slugger.slugify_downcase(content)
Earmark.AstTools.merge_atts_in_node(n, id: slug)
node ->
node
end
[
Earmark.TagSpecificProcessors.new([
{"h1", heading},
{"h2", heading},
{"h3", heading},
{"h4", heading},
{"h5", heading},
{"h6", heading}
])
]
end
end