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.
 
 

38 lines
1.3 KiB

  1. defmodule Microformats2 do
  2. def parse(content) when is_bitstring(content) do
  3. doc = Floki.parse(content)
  4. rels = parse_rels(doc)
  5. %{items: [], rels: rels[:rels], rel_urls: rels[:rel_urls]}
  6. end
  7. defp parse_rels(doc) do
  8. link_rels = Floki.find(doc, "[rel][href]") |>
  9. Enum.filter(fn(element) ->
  10. rel = Floki.attribute(element, "rel") |> List.first
  11. href = Floki.attribute(element, "href") |> List.first
  12. String.strip(to_string(rel)) != "" and String.strip(to_string(href)) != ""
  13. end) |>
  14. Enum.reduce(%{rels: %{}, rel_urls: %{}}, fn(element, acc) ->
  15. rel = Floki.attribute(element, "rel") |> List.first |> String.split(" ", trim: true)
  16. url = Floki.attribute(element, "href") |> List.first # TODO convert to absolute URL
  17. n_map = Enum.reduce(rel, acc, fn(rel, map) ->
  18. if map[:rels][rel] == nil do
  19. Map.put(map, :rels, Map.put(map[:rels], rel, [url]))
  20. else
  21. Map.put(map, :rels, Map.put(map[:rels], rel, Enum.uniq(map[:rels][rel] ++ [url])))
  22. end
  23. end)
  24. if n_map[:rel_urls][url] == nil do
  25. Map.put(n_map, :rel_urls, Map.put(n_map[:rel_urls], url, rel))
  26. else
  27. Map.put(n_map, :rel_urls, Map.put(n_map[:rel_urls], url, Enum.uniq(n_map[:rel_urls][url] ++ rel)))
  28. end
  29. end)
  30. link_rels
  31. end
  32. end