defmodule Lain do @moduledoc """ Documentation for `Lain`. """ use Phoenix.Component require Logger import Phoenix.LiveViewTest, only: [rendered_to_string: 1] alias Lain.Frontmatter alias Lain.Markdown @base_caller __ENV__ 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 clean(base_path) do base_path |> Path.join("**") |> Path.wildcard() |> Enum.each(fn path -> if File.dir?(path) do if !File.exists?(Path.join(path, ".keep")) do File.exists?(path) && File.rm_rf!(path) end else File.exists?(path) && File.rm!(path) end end) end def run(path) do TreeSitter.install_and_run(["-V"]) posts = path |> Path.join("**/*.md") |> Path.wildcard() |> Enum.map(&read/1) |> Enum.map(&validate/1) |> Enum.filter(fn {:error, error} -> Logger.warning(error) false {:ok, _other} -> true end) |> Enum.map(&elem(&1, 1)) |> Enum.sort_by(&Map.get(&1, "date"), :desc) |> Enum.map(&atomize_keys/1) make_feed(posts, path) make_sitemap(posts, path) index = make_index(posts) Lain.LinkLog.run(path) Lain.Static.run(path) Enum.map([index | posts], &write_page(&1, path)) end def atomize_keys(page) do page |> Enum.map(fn {key, value} -> {String.to_atom(key), value} end) |> Enum.into(%{}) end def make_index(posts) do assigns = %{posts: posts} body = ~H""" <%= for post <- @posts do %>