84 lines
2.1 KiB
Elixir
84 lines
2.1 KiB
Elixir
defmodule OrgGarden.Index do
|
|
@moduledoc """
|
|
Generates a fallback `index.md` in the content directory if none was
|
|
exported from an `.org` file.
|
|
|
|
The generated index lists all markdown pages alphabetically with links.
|
|
"""
|
|
|
|
@doc """
|
|
Generate `content_dir/index.md` if it does not already exist.
|
|
|
|
If an `index.md` was already created by ox-hugo (from an `index.org`),
|
|
it is left untouched.
|
|
"""
|
|
@spec generate(String.t()) :: :ok
|
|
def generate(content_dir) do
|
|
index_path = Path.join(content_dir, "index.md")
|
|
|
|
unless File.exists?(index_path) do
|
|
IO.puts(" generating default index.md")
|
|
|
|
pages =
|
|
Path.join(content_dir, "**/*.md")
|
|
|> Path.wildcard()
|
|
|> Enum.map(fn path ->
|
|
slug = Path.relative_to(path, content_dir) |> Path.rootname()
|
|
|
|
title =
|
|
path
|
|
|> File.read!()
|
|
|> then(fn content ->
|
|
case Regex.run(~r/^title\s*=\s*"(.+)"/m, content) do
|
|
[_, t] -> t
|
|
_ -> slug
|
|
end
|
|
end)
|
|
|
|
{slug, title}
|
|
end)
|
|
|> Enum.sort_by(fn {_, title} -> title end)
|
|
|> Enum.map(fn {slug, title} -> "- [#{title}](#{slug})" end)
|
|
|> Enum.join("\n")
|
|
|
|
File.write!(index_path, """
|
|
---
|
|
title: Index
|
|
---
|
|
|
|
#{pages}
|
|
""")
|
|
end
|
|
|
|
:ok
|
|
end
|
|
|
|
@doc """
|
|
Regenerate the index by removing any previously generated one first.
|
|
|
|
Only removes the index if it was generated by us (contains `title: Index`).
|
|
User-exported index files (from `index.org`) are left untouched.
|
|
"""
|
|
@spec regenerate(String.t()) :: :ok
|
|
def regenerate(content_dir) do
|
|
index_path = Path.join(content_dir, "index.md")
|
|
|
|
if File.exists?(index_path) do
|
|
content = File.read!(index_path)
|
|
|
|
if generated_index?(content) do
|
|
File.rm!(index_path)
|
|
end
|
|
end
|
|
|
|
generate(content_dir)
|
|
end
|
|
|
|
defp generated_index?(content) do
|
|
# Our generated index uses "title: Index" in YAML frontmatter.
|
|
# ox-hugo uses TOML frontmatter (title = "..."), so this won't
|
|
# match user-exported files.
|
|
String.contains?(content, "title: Index")
|
|
end
|
|
end
|