-
Notifications
You must be signed in to change notification settings - Fork 1
/
edge_detection.ex
76 lines (60 loc) · 1.71 KB
/
edge_detection.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
defmodule AppAnimal.ParagraphFocus.Perceptual.EdgeDetection do
use Private
require Logger
alias AppAnimal.Neural.WithoutReply
alias AppAnimal.ParagraphFocus.{Environment, Control}
@summary %{mechanism: :flow_emulator,
upstream: Environment,
downstream: [Control.AttendToEditing, Control.AttendToFragments]
}
def activate() do
paragraph_shape = GenServer.call(@summary.upstream, summarize_with: &edge_structure/1)
Logger.info("edge structure: #{edge_string paragraph_shape}")
WithoutReply.activate(@summary.downstream, transmitting: paragraph_shape)
end
def edge_structure(string) do
# Three passes over the string, whee!
parts = decompose(string)
labels = classify(parts)
ranges = ranges(parts)
List.zip([labels, ranges])
end
private do
@gap_definition ~r/\n\n+/
def decompose(string) do
string
|> String.split(@gap_definition, include_captures: true)
|> Enum.reject(&(&1 == ""))
end
def classify(decomposed_string) do
Enum.map(decomposed_string, fn snippet ->
if String.match?(snippet, @gap_definition) do
:gap
else
:text
end
end)
end
def ranges(decomposed_string) do
reducer = fn string, {next_start, ranges} ->
length = String.length(string)
next_next_start = next_start + length
range = next_start..(next_start+length-1)
{next_next_start, [range | ranges]}
end
decomposed_string
|> Enum.reduce({0, []}, reducer)
|> elem(1)
|> Enum.reverse
end
end
def edge_string(structure) do
classifier = fn
{:text, _} -> "\u25A0"
{:gap, _} -> "_"
end
structure
|> Enum.map(classifier)
|> Enum.join
end
end