ast_walker.ex (1903B)
1 defmodule EarmarkParser.Ast.Renderer.AstWalker do 2 3 @moduledoc false 4 5 def walk(anything, fun, ignore_map_keys \\ false), do: _walk(anything, fun, ignore_map_keys, false) 6 7 def walk_ast(ast, fun), do: _walk_ast(ast, fun, []) 8 9 10 defp _walk(ast, fun, ignore_map_keys, child_of_map) 11 defp _walk([], _fun, _ignore_map_keys, _child_of_map), do: [] 12 defp _walk(list, fun, ignore_map_keys, _child_of_map) when is_list(list) do 13 Enum.map(list, &(_walk(&1, fun, ignore_map_keys, false))) 14 end 15 defp _walk(map, fun, ignore_map_keys, _child_of_map) when is_map(map) do 16 map 17 |> Enum.into(%{}, &(_walk(&1, fun, ignore_map_keys, true))) 18 end 19 defp _walk(tuple, fun, ignore_map_keys, child_of_map) when is_tuple(tuple) do 20 if child_of_map && ignore_map_keys do 21 _walk_map_element(tuple, fun, ignore_map_keys) 22 else 23 tuple 24 |> Tuple.to_list 25 |> Enum.map(&(_walk(&1, fun, ignore_map_keys, false))) 26 |> List.to_tuple 27 end 28 end 29 defp _walk(ele, fun, _ignore_map_keys, _child_of_map), do: fun.(ele) 30 31 defp _walk_map_element({key, value}, fun, ignore_map_keys) do 32 {key, _walk(value, fun, ignore_map_keys, false)} 33 end 34 35 36 defp _walk_ast(ast, fun, res) 37 defp _walk_ast([], _fun, res), do: Enum.reverse(res) 38 defp _walk_ast(stringy, fun, res) when is_binary(stringy), do: _walk_ast([stringy], fun, res) 39 defp _walk_ast([stringy|rest], fun, res) when is_binary(stringy) do 40 res1 = 41 case fun.(stringy) do 42 [] -> res 43 [_|_]=trans -> List.flatten([Enum.reverse(trans)|res]) 44 stringy1 -> [stringy1|res] 45 end 46 _walk_ast(rest, fun, res1) 47 end 48 defp _walk_ast([{tag, atts, content, meta}|rest], fun, res) do 49 _walk_ast(rest, fun, [{tag, atts, _walk_ast(content, fun, []), meta}|res]) 50 end 51 defp _walk_ast([list|rest], fun, res) when is_list(list) do 52 _walk_ast(rest, fun, [_walk_ast(list, fun, [])|res]) 53 end 54 end