Files
phoenix-ausblick/lib/outlook/internal_tree/tunit_modifications.ex
Thelonius Kort c8d1639afa Fix ugly bug
2023-06-09 13:57:05 +02:00

83 lines
2.5 KiB
Elixir

defmodule Outlook.InternalTree.TunitModifications do
alias Outlook.InternalTree.{InternalNode,TranslationUnit}
def modifiers do
[
%{
name: "unite_with_next",
fn: &unite_with_next/2,
label: "Unite with next",
description: "unite selected translation unit with (unselected) next"
},
# %{
# name: "split_tunit",
# fn: &split_tunit/2,
# label: "Split Translation unit",
# description: "split translation unit into two"
# }
]
end
# Modifier functions
defp unite_with_next(nodelist, tu_ids) when is_list(tu_ids) do
ids_to_process = Enum.reverse(tu_ids)
Enum.reduce(ids_to_process, nodelist, fn id, nodes -> unite_with_next(nodes, id) end)
end
defp unite_with_next(nodelist, tu_id) do
ind = Enum.find_index(nodelist, fn n -> n.nid == tu_id end)
nodes = Enum.slice(nodelist, ind, 2)
unite_with_next(nodelist, ind, nodes)
end
defp unite_with_next(nodelist, ind, [unit,next]) do
nunit = %TranslationUnit{unit | content: unit.content <> next.content}
nodelist
|> List.replace_at(ind, nunit)
|> List.delete_at(ind + 1)
end
defp unite_with_next(nodelist, _, [_]) do
nodelist
end
defp split_tunit(_nodelist, _tu_ids) do
end
# Function and helpers to apply modifiers
def apply_modifier([ %InternalNode{} = node | rest ], modifier, tu_ids) when node.type == :element do
content = case List.first(node.content) do
%TranslationUnit{} -> process_tunit_list(node.content, modifier, tu_ids)
_ -> apply_modifier(node.content, modifier, tu_ids)
end
[%InternalNode{node| content: content} | apply_modifier(rest, modifier, tu_ids)]
end
def apply_modifier([node | rest], modifier, tu_ids), do: [node | apply_modifier(rest, modifier, tu_ids)]
def apply_modifier([],_, _), do: []
def process_tunit_list(tunits, modifier, tu_ids) do
modi_fun = get_modi_fun(modifier)
ids_to_process = get_ids_to_process(tunits, tu_ids)
case length(ids_to_process) do
0 -> tunits
_ -> modi_fun.(tunits, ids_to_process)
end
end
@doc false
def get_ids_to_process(tunits, tu_ids) do
present_ids = Enum.map(tunits, fn u -> u.nid end)
found_ids = MapSet.new(present_ids)
|> MapSet.intersection(MapSet.new(tu_ids))
|> MapSet.to_list()
# make sure to return ids in the order they occur in tunits
Enum.filter(present_ids, fn pres -> pres in found_ids end)
end
defp get_modi_fun(modifier) do
modifiers()
|> Enum.find(fn m -> m.name == modifier end)
|> Map.get(:fn)
end
end