Maybe
def grouped_by_topics(body_nodes) do
# nil here is a hack, you can run this function in two phases instead
# 1. find the first `h1` with a topic
# 2. then start this function with the rest of `body_nodes`
grouped_by_topics(body_nodes, nil, [], [])
end
# when we meet a `h1` tag, start a new `inner_acc` for collecting the data for the topic in `h1`
defp grouped_by_topics([{"h1", [], ["Topic" <> _ = next_topic]} | rest], prev_topic, prev_inner_acc, outer_acc) do
grouped_by_topics(rest, next_topic, [], [%{prev_topic => prev_inner_acc} | outer_acc])
end
# when we meet a new `p` tag, add it to the `inner_acc` for the current topic
defp grouped_by_topics([{"p", [], ["data" <> _ = new_data]} | rest], current_topic, inner_acc, outer_acc) do
grouped_by_topics(rest, current_topic, [new_data | inner_acc], outer_acc)
end
# neither a `p` nor an `h1` tag -- skip
defp grouped_by_topics([_other | rest], current_topic, inner_acc, outer_acc) do
grouped_by_topics(rest, current_topic, inner_acc, outer_acc)
end
# no more html nodes -- finish
defp grouped_by_topics([], last_topic, inner_acc, outer_acc) do
[%{last_topic => inner_acc} | outer_acc]
end
inner_acc is for collecting data-* in p tags
outer_acc is for collecting %{topic => data (aka final_inner_acc)} maps
current_topic is for keeping the topic from the last h2 tag






















