hugobarauna commited on
Commit
b4554b8
โ€ข
1 Parent(s): 1477b95

Create rune_finder.livemd

Browse files
Files changed (1) hide show
  1. 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
+ ```