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 -> # Match YAML frontmatter: title: "value" or title: value 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 also uses YAML frontmatter now, so we check for our specific # title to distinguish generated vs user-exported index files. String.contains?(content, "title: Index") end end