# Templates will be filled by posts index_template = File.read!("./templates/post_index_page.html") post_template = File.read!("./templates/post_single_page.html") post_feed_item_template = File.read!("./templates/post_item.xml") post_feed_template = File.read!("./templates/posts.xml") # Converting handlebars in template to values fill_template = fn template, pairs -> ~r/{{(.*)}}/U |> Regex.replace(template, fn _, key -> Map.get(pairs, String.to_atom(key)) end) end fill_template_pretemplated = fn template -> &fill_template.(template, &1) end filterCutFileExtension = fn files -> fn ext -> Enum.filter(files, &String.ends_with?(&1, "." <> ext)) |> Enum.map(&String.replace_suffix(&1, "." <> ext, "")) |> (fn x -> %{String.to_atom(ext) => x} end).() end end isMeta = &String.starts_with?(&1, "#+") posts_org = File.ls!("./posts_org") |> Enum.reject(fn x -> String.starts_with?(x, ".") end) |> (fn files -> Enum.map(["org", "html"], filterCutFileExtension.(files)) end).() |> Enum.reduce(%{}, fn x, acc -> Map.merge(x, acc) end) post_contents_org = Enum.filter(Map.get(posts_org, :org), fn el -> Enum.member?(Map.get(posts_org, :html), el) end) |> Enum.map( &(File.read!("./posts_org/" <> &1 <> ".org") |> (fn fileContent -> String.split(fileContent, "\n") end).() |> Enum.take_while(isMeta) |> Enum.map(fn metaOrg -> [head | tail] = String.split(metaOrg, ":") %{ (String.slice(head, 2..-1) |> String.downcase() |> String.to_atom()) => String.slice(Enum.join(tail, ":"), 1..-1) } end) |> Enum.reduce(%{:content => File.read!("./posts_org/" <> &1 <> ".html")}, fn x, acc -> Map.merge(x, acc) end)) ) months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] dateFolder = fn p -> Map.get(p, :date) |> String.slice(8..15) |> String.split(" ") |> (fn ([month, year]) -> year <> "/" <> Integer.to_string(Enum.find_index(months, &(&1 == month)) + 1) <> "/" end).() end normalize_title = fn title -> String.replace(String.downcase(title), " ", "-") end constructLocalPath = fn p -> dateFolder.(p) <> normalize_title.(Map.get(p, :title)) end post_contents = post_contents_org |> Enum.map(fn postMap -> Map.merge(postMap, %{localpath: (constructLocalPath.(postMap))}) end) index_file = post_contents |> Enum.sort_by( &(Map.get(&1, :date) |> String.slice(5..6) |> Integer.parse()) ) |> Enum.reverse() # Group by month |> Enum.group_by(fn m -> Map.get(m, :date) |> String.slice(8..15) end) |> Enum.sort_by(fn {d, _c} -> ((length months) * elem(Integer.parse(String.slice(d, 4..7)), 0)) + Enum.find_index(months, &(&1 == String.slice(d, 0..2))) end) |> Enum.reverse() |> Enum.map(fn {month, posts} -> "\n

" <> month <> "

\n" <> (posts |> Enum.map(fn post -> "

" <> (Map.get(post, :date) |> String.slice(0..6)) <> " - Map.get(post, :localpath) <> ".html\">" <> Map.get(post, :title) <> "

" end) |> Enum.join("\n")) end) |> Enum.join("\n") |> (fn v -> %{index: v} end).() |> fill_template_pretemplated.(index_template).() File.open!("./public/gen/index.html", [:write]) |> IO.binwrite(index_file) |> File.close() prepare_path = fn path -> File.mkdir_p!(Path.dirname(path)) path end post_contents |> Enum.each(fn post -> post |> (fn p -> "./public/gen/" <> Map.get(p, :localpath) <> ".html" end).() |> prepare_path.() |> File.open!([:write]) |> IO.binwrite(fill_template.(post_template, post)) |> File.close() end) stripForRSS = fn content -> content |> String.replace("\n", "") end post_feed = post_contents |> Enum.map(fn m -> Map.update!(m, :content, stripForRSS) end) |> Enum.map(fill_template_pretemplated.(post_feed_item_template)) |> Enum.join("\n") |> (fn v -> %{items: v} end).() |> fill_template_pretemplated.(post_feed_template).() File.open!("./public/gen/rss.xml", [:write]) |> IO.binwrite(post_feed) |> File.close()