emojis_1.0.1_915d688c/src/emojis.adb

  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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
--  SPDX-License-Identifier: Apache-2.0
--
--  Copyright (c) 2021 onox <denkpadje@gmail.com>
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.

with Ada.Strings.UTF_Encoding.Wide_Wide_Strings;

package body Emojis is

   package UTF renames Ada.Strings.UTF_Encoding;

   function Unicode (Number : Long_Integer) return UTF.UTF_8_String is
     (UTF.Wide_Wide_Strings.Encode ("" & Wide_Wide_Character'Val (Number)));

   function Unicode (Number_1, Number_2 : Long_Integer) return UTF.UTF_8_String is
     (UTF.Wide_Wide_Strings.Encode
        (Wide_Wide_Character'Val (Number_1) &
         Wide_Wide_Character'Val (Number_2)));

   function Unicode (Number_1, Number_2, Number_3 : Long_Integer) return UTF.UTF_8_String is
     (UTF.Wide_Wide_Strings.Encode
        (Wide_Wide_Character'Val (Number_1) &
         Wide_Wide_Character'Val (Number_2) &
         Wide_Wide_Character'Val (Number_3)));

   use type SU.Unbounded_String;

   function Labels return String_List is
      Result : String_List
        (1 .. Name_Emojis_1'Length + Name_Emojis_2'Length + Name_Emojis_3'Length);
      Index  : Positive := Result'First;
   begin
      for Pair of Name_Emojis_1 loop
         Result (Index) := Pair.Text;
         Index := Index + 1;
      end loop;

      for Pair of Name_Emojis_2 loop
         Result (Index) := Pair.Text;
         Index := Index + 1;
      end loop;

      for Pair of Name_Emojis_3 loop
         Result (Index) := Pair.Text;
         Index := Index + 1;
      end loop;

      return Result;
   end Labels;

   function Value (Label : String) return String is
   begin
      for Pair of Name_Emojis_3 loop
         if Pair.Text = Label then
            return Unicode (Pair.Point_1, Pair.Point_2, Pair.Point_3);
         end if;
      end loop;

      for Pair of Name_Emojis_2 loop
         if Pair.Text = Label then
            return Unicode (Pair.Point_1, Pair.Point_2) & " ";
         end if;
      end loop;

      for Pair of Name_Emojis_1 loop
         if Pair.Text = Label then
            return Unicode (Pair.Point_1);
         end if;
      end loop;

      return "";
   end Value;

   procedure Replace_Labels (Text : in out SU.Unbounded_String) is
      Text_List : constant String_List := Strings.Split (+Text, Separator => ":");
      Result    : SU.Unbounded_String;
   begin
      for Index in Text_List'Range loop
         if Index mod 2 = 0 then
            declare
               Slice : constant String := +Text_List (Index);
               Emoji : constant String := (if Index < Text_List'Last then Value (Slice) else "");
            begin
               if Emoji /= "" then
                  SU.Append (Result, Emoji);
               else
                  if Index = Text_List'Last then
                     SU.Append (Result, ":" & Slice);
                  else
                     SU.Append (Result, ":" & Slice & ":");
                  end if;
               end if;
            end;
         else
            SU.Append (Result, Text_List (Index));
         end if;
      end loop;

      Text := Result;
   end Replace_Labels;

   function Replace
     (Text        : String;
      Mappings    : Label_Mappings      := Text_Emojis;
      Completions : Completion_Mappings := (1 .. 0 => <>)) return String
   is
      Slices : String_List := Strings.Split (Text, Separator => " ");

      Is_Space : constant Boolean := Slices (Slices'Last) = "";
   begin
      for Index in Slices'Range loop
         declare
            Is_Completion : constant Boolean := Index = Slices'Last - 1 and Is_Space;
         begin
            for Pair of Mappings loop
               if not (for some C of Completions => C = Pair.Text)
                 or (Index < Slices'Last and not Is_Completion)
               then
                  if Slices (Index) = Pair.Text then
                     Slices (Index) := ":" & Pair.Label & ":";
                  end if;
               end if;
            end loop;

            if Completions'Length = 0 or not Is_Completion then
               Replace_Labels (Slices (Index));
            end if;
         end;
      end loop;

      return Strings.Join (Slices, " ");
   end Replace;

end Emojis;