You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.9 KiB

  1. defmodule Microformats2.Rels do
  2. import Microformats2.Helpers
  3. def parse(doc, base_url) do
  4. link_rels =
  5. Floki.find(doc, "[rel][href]")
  6. |> Enum.filter(fn element ->
  7. rel = Floki.attribute(element, "rel") |> List.first()
  8. href = Floki.attribute(element, "href") |> List.first()
  9. String.trim(to_string(rel)) != "" and String.trim(to_string(href)) != ""
  10. end)
  11. |> Enum.reduce(%{rels: %{}, rel_urls: %{}}, fn element, acc ->
  12. rel = attr_list(element, "rel")
  13. url = Floki.attribute(element, "href") |> List.first() |> abs_uri(base_url, doc)
  14. acc
  15. |> save_urls_by_rels(rel, url)
  16. |> save_rels_by_urls(rel, url)
  17. |> save_attributes(element, url)
  18. end)
  19. link_rels
  20. end
  21. defp save_urls_by_rels(map, rel, url) do
  22. Enum.reduce(rel, map, fn rel, nmap ->
  23. if nmap[:rels][rel] == nil,
  24. do: put_in(nmap, [:rels, rel], [url]),
  25. else: put_in(nmap, [:rels, rel], Enum.uniq(nmap[:rels][rel] ++ [url]))
  26. end)
  27. end
  28. defp save_rels_by_urls(map, rel, url) do
  29. if map[:rel_urls][url] == nil,
  30. do: put_in(map, [:rel_urls, url], %{rels: rel}),
  31. else: put_in(map, [:rel_urls, url, :rels], Enum.uniq(map[:rel_urls][url][:rels] ++ rel))
  32. end
  33. defp save_text(map, element, url) do
  34. text = Floki.text(element)
  35. if String.trim(to_string(text)) == "" or map[:rel_urls][url][:text] != nil,
  36. do: map,
  37. else: put_in(map, [:rel_urls, url, :text], text)
  38. end
  39. defp save_attributes(map, element, url) do
  40. Enum.reduce(["hreflang", "media", "title", "type"], save_text(map, element, url), fn att, nmap ->
  41. val = Floki.attribute(element, att) |> List.first()
  42. key = String.to_atom(att)
  43. if String.trim(to_string(val)) == "" or nmap[:rel_urls][url][key] != nil,
  44. do: nmap,
  45. else: put_in(nmap, [:rel_urls, url, key], val)
  46. end)
  47. end
  48. end