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.
 
 

74 lines
2.3 KiB

defmodule Microformats2.Rels do
def parse(doc, base_url) do
link_rels = Floki.find(doc, "[rel][href]") |>
Enum.filter(fn(element) ->
rel = Floki.attribute(element, "rel") |> List.first
href = Floki.attribute(element, "href") |> List.first
String.trim(to_string(rel)) != "" and String.trim(to_string(href)) != ""
end) |>
Enum.reduce(%{rels: %{}, rel_urls: %{}}, fn(element, acc) ->
rel = Microformats2.attr_list(element, "rel")
url = Floki.attribute(element, "href") |> List.first |> Microformats2.abs_uri(base_url, doc)
acc |>
save_urls_by_rels(rel, url) |>
save_rels_by_urls(rel, url) |>
save_attributes(element, url)
end)
link_rels
end
defp save_urls_by_rels(map, rel, url) do
Enum.reduce(rel, map, fn(rel, nmap) ->
if nmap[:rels][rel] == nil do
Map.put(nmap, :rels,
Map.put(nmap[:rels], rel, [url]))
else
Map.put(nmap, :rels,
Map.put(nmap[:rels], rel,
Enum.uniq(nmap[:rels][rel] ++ [url])))
end
end)
end
defp save_rels_by_urls(map, rel, url) do
if map[:rel_urls][url] == nil do
Map.put(map, :rel_urls,
Map.put(map[:rel_urls], url, %{rels: rel}))
else
Map.put(map, :rel_urls,
Map.put(map[:rel_urls], url,
Map.put(map[:rel_urls][url], :rels, Enum.uniq(map[:rel_urls][url][:rels] ++ rel))))
end
end
defp save_text(map, element, url) do
text = Floki.text(element)
if String.trim(to_string(text)) == "" or map[:rel_urls][url][:text] != nil do
map
else
Map.put(map, :rel_urls,
Map.put(map[:rel_urls], url,
Map.put(map[:rel_urls][url], :text, text)))
end
end
defp save_attributes(map, element, url) do
Enum.reduce(["hreflang", "media", "title", "type"],
save_text(map, element, url),
fn(att, nmap) ->
val = Floki.attribute(element, att) |> List.first
if String.trim(to_string(val)) == "" or nmap[:rel_urls][url][String.to_atom(att)] != nil do
nmap
else
Map.put(nmap, :rel_urls,
Map.put(nmap[:rel_urls], url,
Map.put(nmap[:rel_urls][url], String.to_atom(att), val)))
end
end)
end
end