sloane.sh/lib/sloane_sh/context.ex
2024-02-16 22:28:13 -05:00

67 lines
1.8 KiB
Elixir

defmodule SloaneSH.Context do
@moduledoc """
A SloaneSH build context containing configuration and reference to content
files.
"""
use TypedStruct
alias SloaneSH.Config
alias __MODULE__
typedstruct do
field :config, Config.t(), enforce: true
field :pages, [String.t()], default: []
field :posts, [String.t()], default: []
end
def new(config \\ Config.default()) do
%Context{config: config}
end
def init(%Context{config: config} = context) do
with {:ok, pages_contents} <- File.ls(config.pages_dir),
{:ok, posts_contents} <- File.ls(config.posts_dir) do
pages = Enum.filter(pages_contents, &String.match?(&1, ~r/.*\.md$/))
posts = Enum.filter(posts_contents, &String.match?(&1, ~r/.*\.md$/))
%Context{context | pages: pages, posts: posts}
end
end
def maybe_add(%Context{config: config} = ctx, path) do
if Config.in_config?(config, path) do
cond do
String.starts_with?(path, config.pages_dir) ->
page = Path.relative_to(path, config.pages_dir)
%{ctx | pages: Enum.uniq([page | ctx.pages])}
String.starts_with?(path, config.posts_dir) ->
post = Path.relative_to(path, config.posts_dir)
%{ctx | posts: Enum.uniq([post | ctx.posts])}
true ->
ctx
end
else
ctx
end
end
def in_context?(%Context{config: config, pages: pages, posts: posts}, path) do
with true <- Config.in_config?(config, path) do
cond do
String.starts_with?(path, config.pages_dir) ->
page = Path.relative_to(path, config.pages_dir)
[page in pages]
String.starts_with?(path, config.posts_dir) ->
post = Path.relative_to(path, config.posts_dir)
[post in posts]
true ->
false
end
end
end
end