Floki parse and group by heading

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