Spaces:
Running
Running
hugobarauna
commited on
Commit
โข
b4554b8
1
Parent(s):
1477b95
Create rune_finder.livemd
Browse files- public-apps/rune_finder.livemd +121 -0
public-apps/rune_finder.livemd
ADDED
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!-- livebook:{"app_settings":{"access_type":"public","output_type":"rich","show_source":true,"slug":"rune-finder"},"file_entries":[{"name":"UnicodeData.txt","type":"url","url":"https://raw.githubusercontent.com/ramalho/rf/master/elixir/UnicodeData.txt"}]} -->
|
2 |
+
|
3 |
+
# Rune finder
|
4 |
+
|
5 |
+
```elixir
|
6 |
+
Mix.install([
|
7 |
+
{:kino, "~> 0.12.3"}
|
8 |
+
])
|
9 |
+
```
|
10 |
+
|
11 |
+
## About this
|
12 |
+
|
13 |
+
```elixir
|
14 |
+
import Kino.Shorts
|
15 |
+
```
|
16 |
+
|
17 |
+
````elixir
|
18 |
+
markdown("""
|
19 |
+
<details>
|
20 |
+
<summary>About this app</summary>
|
21 |
+
|
22 |
+
Find Unicode characters by name.
|
23 |
+
|
24 |
+
For example, for `face cat`
|
25 |
+
|
26 |
+
```
|
27 |
+
U+1F431 ๐ฑ CAT FACE
|
28 |
+
U+1F638 ๐ธ GRINNING CAT FACE WITH SMILING EYES
|
29 |
+
U+1F639 ๐น CAT FACE WITH TEARS OF JOY
|
30 |
+
U+1F63A ๐บ SMILING CAT FACE WITH OPEN MOUTH
|
31 |
+
U+1F63B ๐ป SMILING CAT FACE WITH HEART-SHAPED EYES
|
32 |
+
U+1F63C ๐ผ CAT FACE WITH WRY SMILE
|
33 |
+
U+1F63D ๐ฝ KISSING CAT FACE WITH CLOSED EYES
|
34 |
+
U+1F63E ๐พ POUTING CAT FACE
|
35 |
+
U+1F63F ๐ฟ CRYING CAT FACE
|
36 |
+
U+1F640 ๐ WEARY CAT FACE
|
37 |
+
```
|
38 |
+
|
39 |
+
</details>
|
40 |
+
""")
|
41 |
+
````
|
42 |
+
|
43 |
+
## Code
|
44 |
+
|
45 |
+
```elixir
|
46 |
+
content =
|
47 |
+
Kino.FS.file_path("UnicodeData.txt")
|
48 |
+
|> File.read!()
|
49 |
+
```
|
50 |
+
|
51 |
+
```elixir
|
52 |
+
defmodule RuneFinder do
|
53 |
+
defp to_rune(code, name) do
|
54 |
+
rune = <<String.to_integer(code, 16)::utf8>>
|
55 |
+
"U+#{code}\t#{rune}\t#{name}"
|
56 |
+
end
|
57 |
+
|
58 |
+
defp select(line_stream, query_words) do
|
59 |
+
Enum.map(line_stream, fn line ->
|
60 |
+
[code, name | _] = String.split(line, ";")
|
61 |
+
|
62 |
+
if MapSet.subset?(query_words, tokenize(name)), do: to_rune(code, name)
|
63 |
+
end)
|
64 |
+
|> Enum.reject(&(&1 == nil))
|
65 |
+
end
|
66 |
+
|
67 |
+
defp find(query_words) do
|
68 |
+
Kino.FS.file_path("UnicodeData.txt")
|
69 |
+
|> File.stream!()
|
70 |
+
|> select(query_words)
|
71 |
+
end
|
72 |
+
|
73 |
+
defp tokenize(text) do
|
74 |
+
text
|
75 |
+
|> String.replace("-", " ")
|
76 |
+
|> String.split()
|
77 |
+
|> MapSet.new()
|
78 |
+
end
|
79 |
+
|
80 |
+
def main(args) do
|
81 |
+
args
|
82 |
+
|> String.upcase()
|
83 |
+
|> tokenize
|
84 |
+
|> find
|
85 |
+
end
|
86 |
+
end
|
87 |
+
```
|
88 |
+
|
89 |
+
```elixir
|
90 |
+
form =
|
91 |
+
Kino.Control.form(
|
92 |
+
[
|
93 |
+
name: Kino.Input.text("Unicode characters name", default: "face cat")
|
94 |
+
],
|
95 |
+
submit: "Find"
|
96 |
+
)
|
97 |
+
```
|
98 |
+
|
99 |
+
```elixir
|
100 |
+
output_frame = frame()
|
101 |
+
|
102 |
+
Kino.listen(form, fn event ->
|
103 |
+
Kino.Frame.clear(output_frame)
|
104 |
+
|
105 |
+
case event.data.name do
|
106 |
+
"" ->
|
107 |
+
Kino.Frame.render(output_frame, "Please provide words to find.")
|
108 |
+
|
109 |
+
_ ->
|
110 |
+
runes = RuneFinder.main(event.data.name)
|
111 |
+
|
112 |
+
Enum.each(runes, fn rune ->
|
113 |
+
Kino.Frame.append(output_frame, text(rune))
|
114 |
+
end)
|
115 |
+
|
116 |
+
Kino.Frame.append(output_frame, text("\n#{Enum.count(runes)} found"))
|
117 |
+
end
|
118 |
+
end)
|
119 |
+
|
120 |
+
output_frame
|
121 |
+
```
|