Spaces:
Running
Running
File size: 2,455 Bytes
b4554b8 6a67920 b4554b8 6a67920 b4554b8 6a67920 b4554b8 6a67920 b4554b8 |
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
<!-- 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"}]} -->
# Rune finder
```elixir
Mix.install([
{:kino, "~> 0.12.3"}
])
```
## About this
```elixir
import Kino.Shorts
```
````elixir
markdown("""
<details>
<summary>About this app</summary>
Find Unicode characters by name.
For example, for `face cat`
```
U+1F431 ๐ฑ CAT FACE
U+1F638 ๐ธ GRINNING CAT FACE WITH SMILING EYES
U+1F639 ๐น CAT FACE WITH TEARS OF JOY
U+1F63A ๐บ SMILING CAT FACE WITH OPEN MOUTH
U+1F63B ๐ป SMILING CAT FACE WITH HEART-SHAPED EYES
U+1F63C ๐ผ CAT FACE WITH WRY SMILE
U+1F63D ๐ฝ KISSING CAT FACE WITH CLOSED EYES
U+1F63E ๐พ POUTING CAT FACE
U+1F63F ๐ฟ CRYING CAT FACE
U+1F640 ๐ WEARY CAT FACE
```
</details>
""")
````
## Code
```elixir
content =
Kino.FS.file_path("UnicodeData.txt")
|> File.read!()
```
```elixir
defmodule RuneFinder do
defp to_rune(code, name) do
rune = <<String.to_integer(code, 16)::utf8>>
"U+#{code}\t#{rune}\t#{name}"
end
defp select(line_stream, query_words) do
Enum.map(line_stream, fn line ->
[code, name | _] = String.split(line, ";")
if MapSet.subset?(query_words, tokenize(name)), do: to_rune(code, name)
end)
|> Enum.reject(&(&1 == nil))
end
defp find(query_words) do
Kino.FS.file_path("UnicodeData.txt")
|> File.stream!()
|> select(query_words)
end
defp tokenize(text) do
text
|> String.replace("-", " ")
|> String.split()
|> MapSet.new()
end
def main(args) do
args
|> String.upcase()
|> tokenize
|> find
end
end
```
```elixir
form =
Kino.Control.form(
[
name: Kino.Input.text("Unicode characters name", default: "face cat")
],
submit: "Find"
)
```
```elixir
output_frame = frame()
Kino.listen(form, fn event ->
origin = event.origin
Kino.Frame.clear(output_frame, to: origin)
case event.data.name do
"" ->
Kino.Frame.render(output_frame, "Please provide words to find.", to: origin)
_ ->
runes = RuneFinder.main(event.data.name)
Enum.each(runes, fn rune ->
Kino.Frame.append(output_frame, text(rune), to: origin)
end)
Kino.Frame.append(output_frame, text("\n#{Enum.count(runes)} found"), to: origin)
end
end)
output_frame
```
|