This is brittle as all get-out because it makes some serious assumptions about the shape of the data, but:
def extract_topic_maps(html) do
nodes = Floki.find(html, "section.body-copy > *")
{_, topic_maps} =
Enum.reduce(nodes, {nil, []}, fn
{"p", _, _}, {nil, _} -> raise "Invalid state: no topic"
# New topic, set in accumulator
{"h2", _, [topic]}, {_, topic_maps} -> {topic, topic_maps}
# New value in topic, add appropriate topic_map to topic_maps in accumulator
{"p", _, [data]}, {topic, topic_maps} -> {topic, [%{topic: topic, data: data} | topic_maps]}
node, _ -> raise "Invalid state: unexpected node #{inspect(node)}"
end)
Enum.reverse(topic_maps)
end
With your input that returns something like
[
%{data: "data-a", topic: "Topic 1"},
%{data: "data-b", topic: "Topic 1"},
%{data: "data-c", topic: "Topic 1"},
%{data: "data-d", topic: "Topic 2"},
...
]






















