2024-02-24 13:16:56 -05:00
|
|
|
defmodule SloaneSH.Assets.Markdown do
|
|
|
|
@moduledoc """
|
|
|
|
Helper to define markdown, html, and eex templating for pages and posts
|
|
|
|
"""
|
|
|
|
defmacro __using__(opts) do
|
|
|
|
type = Keyword.fetch!(opts, :type)
|
|
|
|
|
|
|
|
quote do
|
2024-02-24 13:40:20 -05:00
|
|
|
import SloaneSH.Layouts.Helpers, warn: false
|
2024-02-24 13:16:56 -05:00
|
|
|
alias SloaneSH.Asset
|
|
|
|
alias SloaneSH.FrontMatter
|
|
|
|
alias SloaneSH.Layouts
|
|
|
|
alias SloaneSH.OutputDirs
|
|
|
|
|
|
|
|
@behaviour Asset
|
|
|
|
|
|
|
|
@impl Asset
|
|
|
|
def extensions(_cfg), do: ~w[.md .html .md.eex .html.eex]
|
|
|
|
|
|
|
|
@impl Asset
|
|
|
|
def attrs(cfg, path, data) do
|
|
|
|
{:ok, attrs, without_attrs} = FrontMatter.parse(data)
|
|
|
|
|
|
|
|
attrs =
|
|
|
|
Map.put_new_lazy(attrs, :permalink, fn ->
|
|
|
|
output = apply(OutputDirs, unquote(type), [cfg, path])
|
|
|
|
permalink = OutputDirs.to_permalink(cfg, output)
|
|
|
|
end)
|
|
|
|
|
|
|
|
attrs = handle_attrs(cfg, path, without_attrs, attrs)
|
|
|
|
|
|
|
|
{:ok, attrs, without_attrs}
|
|
|
|
end
|
|
|
|
|
|
|
|
@impl Asset
|
|
|
|
def render(cfg, ctx, path, data, attrs) do
|
|
|
|
output_path =
|
|
|
|
if attrs[:permalink] do
|
|
|
|
OutputDirs.from_permalink(cfg, attrs[:permalink])
|
|
|
|
else
|
|
|
|
apply(OutputDirs, unquote(type), [cfg, path])
|
|
|
|
end
|
|
|
|
|
|
|
|
output = {output_path, do_render(ctx, path, data, attrs)}
|
|
|
|
{:ok, [output]}
|
|
|
|
end
|
|
|
|
|
|
|
|
defp do_render(ctx, path, data, attrs) when is_binary(path) do
|
|
|
|
do_render(ctx, base_and_ext(path), data, attrs)
|
|
|
|
end
|
|
|
|
|
|
|
|
defp do_render(ctx, {path, ".eex"}, data, attrs) do
|
2024-02-24 13:40:20 -05:00
|
|
|
eexed = eval_eex(data, "#{path}.eex", ctx, attrs)
|
2024-02-24 13:16:56 -05:00
|
|
|
do_render(ctx, base_and_ext(path), eexed, attrs)
|
|
|
|
end
|
|
|
|
|
|
|
|
defp do_render(ctx, {path, ".md"}, data, attrs) do
|
|
|
|
html = Earmark.as_html!(data)
|
|
|
|
do_render(ctx, {path, ".html"}, html, attrs)
|
|
|
|
end
|
|
|
|
|
|
|
|
defp do_render(ctx, {_path, ".html"}, data, attrs) do
|
|
|
|
apply(Layouts, unquote(type), [data, ctx, attrs])
|
|
|
|
end
|
|
|
|
|
|
|
|
defp base_and_ext(path) do
|
|
|
|
ext = Path.extname(path)
|
|
|
|
base = Path.basename(path, ext)
|
|
|
|
{base, ext}
|
|
|
|
end
|
|
|
|
|
2024-02-24 13:40:20 -05:00
|
|
|
defp eval_eex(template, file, ctx, attrs) do
|
|
|
|
{result, _binding} =
|
|
|
|
template
|
|
|
|
|> EEx.compile_string(file: file)
|
|
|
|
|> Code.eval_quoted([ctx: ctx, attrs: attrs], __ENV__)
|
|
|
|
|
|
|
|
result
|
|
|
|
end
|
|
|
|
|
2024-02-24 13:16:56 -05:00
|
|
|
def handle_attrs(cfg, path, data, attrs) do
|
|
|
|
attrs
|
|
|
|
end
|
|
|
|
|
|
|
|
defoverridable handle_attrs: 4
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|