pre.hn/lib/pre_dot_hn.ex

107 lines
2.4 KiB
Elixir
Raw Normal View History

2023-09-18 18:21:59 +00:00
defmodule PreDotHn do
@moduledoc """
Documentation for `PreDotHn`.
"""
2023-09-22 12:58:31 +00:00
use Phoenix.Component
2023-09-18 18:21:59 +00:00
2023-09-22 12:58:31 +00:00
require Logger
2023-09-18 18:21:59 +00:00
2023-09-22 12:58:31 +00:00
import Phoenix.LiveViewTest, only: [rendered_to_string: 1]
2023-09-18 18:21:59 +00:00
2023-09-22 12:58:31 +00:00
alias PreDotHn.Frontmatter
alias PreDotHn.Markdown
def read(path) do
path
|> File.read!()
|> Frontmatter.front_matter_split()
|> then(fn {frontmatter_text, body_text} ->
{Frontmatter.make_frontmatter(path, frontmatter_text), body_text}
end)
|> then(fn {frontmatter, body_text} ->
body = Markdown.render(body_text)
Map.merge(frontmatter, %{"body" => body, "path" => path})
end)
end
def validate(%{"slug" => nil, "path" => path}) do
{:error, "slug missing from #{path}"}
end
def validate(%{"slug" => "", "path" => path}) do
{:error, "slug missing from #{path}"}
end
def validate(other), do: {:ok, other}
def run() do
"site/**/*.md"
|> Path.wildcard()
|> Enum.map(&read/1)
|> Enum.map(&validate/1)
|> Enum.filter(fn
{:error, error} ->
Logger.warn(error)
false
{:ok, _other} ->
true
end)
|> Enum.map(fn {:ok, page} ->
page =
page |> Enum.map(fn {key, value} -> {String.to_atom(key), value} end) |> Enum.into(%{})
write_page(page)
end)
end
slot(:inner_block, required: true)
def layout(assigns) do
~H"""
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>A Basic HTML5 Template</title>
<meta name="description" content="A simple HTML5 Template for new projects.">
<meta name="author" content="SitePoint">
<link rel="icon" href="/favicon.ico">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="stylesheet" href="/assets/app.css?v=1.0">
</head>
<body class="bg-dark font-mono text-light">
<%= render_slot(@inner_block) %>
</body>
</html>
"""
end
def write_page(%{slug: slug} = assigns) do
filename = "#{slug}.html"
path = Path.join(["priv", "static", filename])
~H"""
<.layout>
<main class="container mx-auto">
<section class="box border border-light">
<%= {:safe, @body} %>
</section>
</main>
</.layout>
"""
|> rendered_to_string()
|> then(&File.write!(path, &1))
2023-09-18 18:21:59 +00:00
end
end