3696 lines
172 KiB
Diff
3696 lines
172 KiB
Diff
From 0432aa66b8728bc266da3c2cca84587bc44b3557 Mon Sep 17 00:00:00 2001
|
||
From: Matthias Clasen <mclasen@redhat.com>
|
||
Date: Tue, 8 Mar 2016 11:16:24 +0900
|
||
Subject: [PATCH] Don't warn if DISPLAY is not set
|
||
|
||
This is normal under Wayland, and not worth warning about.
|
||
The warnings disrupt unit tests in GNOME continuous, which
|
||
treat warnings as fatal.
|
||
|
||
BUG=https://github.com/ibus/ibus/pull/1844
|
||
R=shawn.p.huang@gmail.com
|
||
|
||
Review URL: https://codereview.appspot.com/289430043
|
||
|
||
Patch from Matthias Clasen <mclasen@redhat.com>.
|
||
---
|
||
src/ibusshare.c | 5 +----
|
||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||
|
||
diff --git a/src/ibusshare.c b/src/ibusshare.c
|
||
index 63800a6..b793a96 100644
|
||
--- a/src/ibusshare.c
|
||
+++ b/src/ibusshare.c
|
||
@@ -113,10 +113,7 @@ ibus_get_socket_path (void)
|
||
display = g_strdup (_display);
|
||
}
|
||
|
||
- if (display == NULL) {
|
||
- g_warning ("DISPLAY is empty! We use default DISPLAY (:0.0)");
|
||
- }
|
||
- else {
|
||
+ if (display) {
|
||
p = display;
|
||
hostname = display;
|
||
for (; *p != ':' && *p != '\0'; p++);
|
||
--
|
||
2.7.4
|
||
|
||
From 84c18f1d382548c52138822a11473d2dac79e485 Mon Sep 17 00:00:00 2001
|
||
From: Rui Matos <tiagomatos@gmail.com>
|
||
Date: Wed, 25 May 2016 11:21:09 +0900
|
||
Subject: [PATCH] Install a DBus service file
|
||
|
||
With the transition to user scoped DBus sessions (vs. login sessions)
|
||
there's a need to start ibus-daemon via DBus activation so that the
|
||
process gets properly tracked and disposed of when the login session
|
||
ends. Otherwise the ibus-daemon process lingers on and keeps the whole
|
||
login session up.
|
||
|
||
We already connect and own a well known name on DBus. The remaining
|
||
missing piece is the DBus service file which we introduce here.
|
||
|
||
BUG=https://github.com/ibus/ibus/pull/1853
|
||
R=Shawn.P.Huang@gmail.com
|
||
|
||
Review URL: https://codereview.appspot.com/295340043
|
||
|
||
Patch from Rui Matos <tiagomatos@gmail.com>.
|
||
---
|
||
bus/Makefile.am | 11 +++++++++++
|
||
bus/org.freedesktop.IBus.service.in | 3 +++
|
||
2 files changed, 14 insertions(+)
|
||
create mode 100644 bus/org.freedesktop.IBus.service.in
|
||
|
||
diff --git a/bus/Makefile.am b/bus/Makefile.am
|
||
index 26cb2f8..4dabacf 100644
|
||
--- a/bus/Makefile.am
|
||
+++ b/bus/Makefile.am
|
||
@@ -174,4 +174,15 @@ man_onedir = $(mandir)/man1
|
||
%.1.gz: %.1
|
||
$(AM_V_GEN) gzip -c $< > $@.tmp && mv $@.tmp $@
|
||
|
||
+
|
||
+dbusservice_in_files = org.freedesktop.IBus.service.in
|
||
+dbusservice_DATA = $(dbusservice_in_files:.service.in=.service)
|
||
+dbusservicedir=${datadir}/dbus-1/services
|
||
+
|
||
+org.freedesktop.IBus.service: org.freedesktop.IBus.service.in
|
||
+ $(AM_V_GEN) sed -e "s|\@bindir\@|$(bindir)|" $< > $@.tmp && mv $@.tmp $@
|
||
+
|
||
+EXTRA_DIST += $(dbusservice_in_files)
|
||
+CLEANFILES += $(dbusservice_DATA)
|
||
+
|
||
-include $(top_srcdir)/git.mk
|
||
diff --git a/bus/org.freedesktop.IBus.service.in b/bus/org.freedesktop.IBus.service.in
|
||
new file mode 100644
|
||
index 0000000..cc88834
|
||
--- /dev/null
|
||
+++ b/bus/org.freedesktop.IBus.service.in
|
||
@@ -0,0 +1,3 @@
|
||
+[D-BUS Service]
|
||
+Name=org.freedesktop.IBus
|
||
+Exec=@bindir@/ibus-daemon --replace --xim --panel disable
|
||
--
|
||
2.7.4
|
||
|
||
From 3ef21fef0135f7b4fe9611d201f15611734f6c51 Mon Sep 17 00:00:00 2001
|
||
From: fujiwarat <takao.fujiwara1@gmail.com>
|
||
Date: Fri, 3 Jun 2016 11:52:29 +0900
|
||
Subject: [PATCH] client/gtk2: Fix SEGV with Wayland display
|
||
|
||
Delete gdk_display_get_name() in GTK clients because ibus-daemon
|
||
does not use gdk_display_get_name().
|
||
GdkX11Dislay and GdkX11Window does not work with Wayland.
|
||
|
||
BUG=https://github.com/ibus/ibus/issues/1859
|
||
R=Shawn.P.Huang@gmail.com
|
||
|
||
Review URL: https://codereview.appspot.com/301760043
|
||
---
|
||
client/gtk2/ibusimcontext.c | 5 -----
|
||
setup/main.py | 7 +++++--
|
||
2 files changed, 5 insertions(+), 7 deletions(-)
|
||
|
||
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
|
||
index 9d927e6..0df0062 100644
|
||
--- a/client/gtk2/ibusimcontext.c
|
||
+++ b/client/gtk2/ibusimcontext.c
|
||
@@ -583,11 +583,6 @@ ibus_im_context_class_init (IBusIMContextClass *class)
|
||
|
||
/* init bus object */
|
||
if (_bus == NULL) {
|
||
- const gchar *dname = gdk_display_get_name (gdk_display_get_default ());
|
||
- /* ibus-daemon uses DISPLAY variable. */
|
||
- if (g_strcmp0 (dname, "Wayland") == 0)
|
||
- dname = g_getenv ("DISPLAY");
|
||
- ibus_set_display (dname);
|
||
_bus = ibus_bus_new_async ();
|
||
|
||
/* init the global fake context */
|
||
diff --git a/setup/main.py b/setup/main.py
|
||
index 26c2b0f..e1f7a9d 100644
|
||
--- a/setup/main.py
|
||
+++ b/setup/main.py
|
||
@@ -275,8 +275,11 @@ class Setup(object):
|
||
self.__init_general()
|
||
|
||
def __gdk_window_set_cb(self, object, pspec):
|
||
- str = '%u' % GdkX11.X11Window.get_xid(object.get_window())
|
||
- GLib.setenv('IBUS_SETUP_XID', str, True)
|
||
+ window = object.get_window()
|
||
+ if type(window) != GdkX11.X11Window:
|
||
+ return
|
||
+ s = '%u' % GdkX11.X11Window.get_xid(window)
|
||
+ GLib.setenv('IBUS_SETUP_XID', s, True)
|
||
|
||
def __combobox_notify_active_engine_cb(self, combobox, property):
|
||
engine = self.__combobox.get_active_engine()
|
||
--
|
||
2.7.4
|
||
|
||
From a598ae29223d1ca25e76bf7d7de9703f63ea337e Mon Sep 17 00:00:00 2001
|
||
From: fujiwarat <takao.fujiwara1@gmail.com>
|
||
Date: Fri, 3 Jun 2016 19:44:11 +0900
|
||
Subject: [PATCH] ui/gtk3: Fix panel CSS format for GTK 3.20
|
||
|
||
CSS node names have been changed since GTK 3.20 and the font size and
|
||
widget color no longer work with the previous node names.
|
||
|
||
BUG=https://github.com/ibus/ibus/issues/1856
|
||
|
||
Review URL: https://codereview.appspot.com/297380043
|
||
---
|
||
ui/gtk3/candidatearea.vala | 16 +++++++++++++---
|
||
ui/gtk3/handle.vala | 10 ++++++++--
|
||
ui/gtk3/panel.vala | 9 +++++++--
|
||
3 files changed, 28 insertions(+), 7 deletions(-)
|
||
|
||
diff --git a/ui/gtk3/candidatearea.vala b/ui/gtk3/candidatearea.vala
|
||
index c969312..3848f0d 100644
|
||
--- a/ui/gtk3/candidatearea.vala
|
||
+++ b/ui/gtk3/candidatearea.vala
|
||
@@ -3,7 +3,7 @@
|
||
* ibus - The Input Bus
|
||
*
|
||
* Copyright(c) 2011-2015 Peng Huang <shawn.p.huang@gmail.com>
|
||
- * Copyright(c) 2015 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
||
+ * Copyright(c) 2015-2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
||
*
|
||
* This library is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU Lesser General Public
|
||
@@ -31,6 +31,10 @@ class CandidateArea : Gtk.Box {
|
||
private uint m_focus_candidate;
|
||
private bool m_show_cursor;
|
||
|
||
+ private bool m_use_latest_css_format =
|
||
+ ((Gtk.MAJOR_VERSION > 3) ||
|
||
+ (Gtk.MAJOR_VERSION == 3) && (Gtk.MINOR_VERSION >= 20));
|
||
+
|
||
private const string LABELS[] = {
|
||
"1.", "2.", "3.", "4.", "5.", "6.", "7.", "8.",
|
||
"9.", "0.", "a.", "b.", "c.", "d.", "e.", "f."
|
||
@@ -103,7 +107,8 @@ class CandidateArea : Gtk.Box {
|
||
Pango.AttrList attrs = get_pango_attr_list_from_ibus_text(candidates[i]);
|
||
if (i == focus_candidate && show_cursor) {
|
||
Gtk.StyleContext context = m_candidates[i].get_style_context();
|
||
- Gdk.RGBA color = context.get_color(Gtk.StateFlags.SELECTED);
|
||
+ Gdk.RGBA *color = null;
|
||
+ context.get(Gtk.StateFlags.SELECTED, "color", out color);
|
||
Pango.Attribute pango_attr = Pango.attr_foreground_new(
|
||
(uint16)(color.red * uint16.MAX),
|
||
(uint16)(color.green * uint16.MAX),
|
||
@@ -112,7 +117,12 @@ class CandidateArea : Gtk.Box {
|
||
pango_attr.end_index = candidates[i].get_text().length;
|
||
attrs.insert((owned)pango_attr);
|
||
|
||
- color = context.get_background_color(Gtk.StateFlags.SELECTED);
|
||
+ color = null;
|
||
+ string bg_prop =
|
||
+ m_use_latest_css_format
|
||
+ ? "-gtk-secondary-caret-color"
|
||
+ : "background-color";
|
||
+ context.get(Gtk.StateFlags.SELECTED, bg_prop, out color);
|
||
pango_attr = Pango.attr_background_new(
|
||
(uint16)(color.red * uint16.MAX),
|
||
(uint16)(color.green * uint16.MAX),
|
||
diff --git a/ui/gtk3/handle.vala b/ui/gtk3/handle.vala
|
||
index 1edb537..bef5e8b 100644
|
||
--- a/ui/gtk3/handle.vala
|
||
+++ b/ui/gtk3/handle.vala
|
||
@@ -2,7 +2,8 @@
|
||
*
|
||
* ibus - The Input Bus
|
||
*
|
||
- * Copyright(c) 2011-2015 Peng Huang <shawn.p.huang@gmail.com>
|
||
+ * Copyright(c) 2011-2016 Peng Huang <shawn.p.huang@gmail.com>
|
||
+ * Copyright(c) 2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
||
*
|
||
* This library is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU Lesser General Public
|
||
@@ -29,6 +30,11 @@ class Handle : Gtk.EventBox {
|
||
public signal void move_end();
|
||
|
||
public Handle() {
|
||
+ // Call base class constructor
|
||
+ GLib.Object(
|
||
+ name : "IBusHandle"
|
||
+ );
|
||
+
|
||
set_size_request(6, -1);
|
||
Gdk.EventMask mask = Gdk.EventMask.EXPOSURE_MASK |
|
||
Gdk.EventMask.BUTTON_PRESS_MASK |
|
||
@@ -42,7 +48,7 @@ class Handle : Gtk.EventBox {
|
||
Gtk.CssProvider css_provider = new Gtk.CssProvider();
|
||
try {
|
||
css_provider.load_from_data(
|
||
- "GtkEventBox { background-color: gray }", -1);
|
||
+ "#IBusHandle { background-color: gray }", -1);
|
||
} catch (GLib.Error error) {
|
||
warning("Parse error in Handle: %s", error.message);
|
||
}
|
||
diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
|
||
index 2ca3a5e..cc19350 100644
|
||
--- a/ui/gtk3/panel.vala
|
||
+++ b/ui/gtk3/panel.vala
|
||
@@ -3,7 +3,7 @@
|
||
* ibus - The Input Bus
|
||
*
|
||
* Copyright(c) 2011-2014 Peng Huang <shawn.p.huang@gmail.com>
|
||
- * Copyright(c) 2015 Takao Fujwiara <takao.fujiwara1@gmail.com>
|
||
+ * Copyright(c) 2015-2016 Takao Fujwiara <takao.fujiwara1@gmail.com>
|
||
*
|
||
* This library is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU Lesser General Public
|
||
@@ -543,7 +543,12 @@ class Panel : IBus.PanelService {
|
||
return;
|
||
}
|
||
|
||
- string data_format = "GtkLabel { font: %s; }";
|
||
+ string data_format = "label { font: %s; }";
|
||
+ if (Gtk.MAJOR_VERSION < 3 ||
|
||
+ (Gtk.MAJOR_VERSION == 3 && Gtk.MINOR_VERSION < 20)) {
|
||
+ data_format = "GtkLabel { font: %s; }";
|
||
+ }
|
||
+
|
||
string data = data_format.printf(font_name);
|
||
m_css_provider = new Gtk.CssProvider();
|
||
|
||
--
|
||
2.7.4
|
||
|
||
From 160d3c975af91eea6b8271b757be769b8ceef98d Mon Sep 17 00:00:00 2001
|
||
From: fujiwarat <takao.fujiwara1@gmail.com>
|
||
Date: Tue, 21 Jun 2016 18:10:21 +0900
|
||
Subject: [PATCH 1/4] engine: Implement Emoji typing with XKB engines
|
||
|
||
Now Ctrl+Shift+e can convert an Emoji annotation to the Emoji characters
|
||
likes Ctrl+Shift+u.
|
||
The annotations are described as "Keywords" in the Unicode Emoji Data:
|
||
http://www.unicode.org/emoji/charts/emoji-list.html
|
||
'emoji-parser' compiles 'emoji-list.html' and generates 'emoji.dict'
|
||
|
||
Review URL: https://codereview.appspot.com/295610043
|
||
---
|
||
configure.ac | 16 ++
|
||
src/Makefile.am | 31 ++++
|
||
src/emoji-parser.c | 217 ++++++++++++++++++++++++
|
||
src/ibusenginesimple.c | 443 ++++++++++++++++++++++++++++++++++++++++++++-----
|
||
src/ibusutil.c | 193 ++++++++++++++++++++-
|
||
src/ibusutil.h | 31 +++-
|
||
6 files changed, 890 insertions(+), 41 deletions(-)
|
||
create mode 100644 src/emoji-parser.c
|
||
|
||
diff --git a/configure.ac b/configure.ac
|
||
index 1e1f5dd..3128ef9 100644
|
||
--- a/configure.ac
|
||
+++ b/configure.ac
|
||
@@ -599,6 +599,21 @@ if test x"$enable_libnotify" = x"yes"; then
|
||
enable_libnotify="yes (enabled, use --disable-libnotify to disable)"
|
||
fi
|
||
|
||
+# --disable-emoji-dict option.
|
||
+AC_ARG_ENABLE(emoji-dict,
|
||
+ AS_HELP_STRING([--disable-emoji-dict],
|
||
+ [Do not build Emoji dict files]),
|
||
+ [enable_emoji_dict=$enableval],
|
||
+ [enable_emoji_dict=yes]
|
||
+)
|
||
+AM_CONDITIONAL([ENABLE_EMOJI_DICT], [test x"$enable_emoji_dict" = x"yes"])
|
||
+if test x"$enable_emoji_dict" = x"yes"; then
|
||
+ PKG_CHECK_MODULES(LIBXML2, [
|
||
+ libxml-2.0
|
||
+ ])
|
||
+ enable_emoji_dict="yes (enabled, use --disable-emoji-dict to disable)"
|
||
+fi
|
||
+
|
||
# Check iso-codes.
|
||
PKG_CHECK_MODULES(ISOCODES, [
|
||
iso-codes
|
||
@@ -682,6 +697,7 @@ Build options:
|
||
Panel icon "$IBUS_ICON_KEYBOARD"
|
||
Enable surrounding-text $enable_surrounding_text
|
||
Enable libnotify $enable_libnotify
|
||
+ Enable Emoji dict $enable_emoji_dict
|
||
Run test cases $enable_tests
|
||
])
|
||
|
||
diff --git a/src/Makefile.am b/src/Makefile.am
|
||
index adaebe9..a33b67d 100644
|
||
--- a/src/Makefile.am
|
||
+++ b/src/Makefile.am
|
||
@@ -231,7 +231,38 @@ ibusmarshalers.c: ibusmarshalers.h ibusmarshalers.list
|
||
$(GLIB_GENMARSHAL) --prefix=_ibus_marshal $(srcdir)/ibusmarshalers.list --body --internal) > $@.tmp && \
|
||
mv $@.tmp $@
|
||
|
||
+if ENABLE_EMOJI_DICT
|
||
+AM_CPPFLAGS += -DENABLE_EMOJI_DICT
|
||
+
|
||
+dictdir = $(pkgdatadir)/dicts
|
||
+dict_DATA = emoji.dict
|
||
+
|
||
+noinst_PROGRAMS = emoji-parser
|
||
+
|
||
+emoji.dict: emoji-parser emoji-list.html
|
||
+ $(builddir)/emoji-parser emoji-list.html $@
|
||
+
|
||
+emoji_parser_SOURCES = \
|
||
+ emoji-parser.c \
|
||
+ $(NULL)
|
||
+emoji_parser_CFLAGS = \
|
||
+ $(GLIB2_CFLAGS) \
|
||
+ $(LIBXML2_CFLAGS) \
|
||
+ $(NULL)
|
||
+emoji_parser_LDADD = \
|
||
+ $(GLIB2_LIBS) \
|
||
+ $(LIBXML2_LIBS) \
|
||
+ $(libibus) \
|
||
+ $(NULL)
|
||
+
|
||
+CLEANFILES += \
|
||
+ $(dict_DATA) \
|
||
+ $(NULL)
|
||
+endif
|
||
+
|
||
EXTRA_DIST = \
|
||
+ emoji-list.html \
|
||
+ emoji-parser.c \
|
||
ibusversion.h.in \
|
||
ibusmarshalers.list \
|
||
ibusenumtypes.h.template \
|
||
diff --git a/src/emoji-parser.c b/src/emoji-parser.c
|
||
new file mode 100644
|
||
index 0000000..cf92fee
|
||
--- /dev/null
|
||
+++ b/src/emoji-parser.c
|
||
@@ -0,0 +1,217 @@
|
||
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
||
+/* vim:set et sts=4: */
|
||
+/* ibus - The Input Bus
|
||
+ * Copyright (C) 2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
||
+ * Copyright (C) 2016 Red Hat, Inc.
|
||
+ *
|
||
+ * This library is free software; you can redistribute it and/or
|
||
+ * modify it under the terms of the GNU Lesser General Public
|
||
+ * License as published by the Free Software Foundation; either
|
||
+ * version 2.1 of the License, or (at your option) any later version.
|
||
+ *
|
||
+ * This library is distributed in the hope that it will be useful,
|
||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ * Lesser General Public License for more details.
|
||
+ *
|
||
+ * You should have received a copy of the GNU Lesser General Public
|
||
+ * License along with this library; if not, write to the Free Software
|
||
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||
+ * USA
|
||
+ */
|
||
+
|
||
+/* Convert http://www.unicode.org/emoji/charts/emoji-list.html
|
||
+ * to the dictionary file which look up the Emoji from the annotation.
|
||
+ */
|
||
+
|
||
+#include <glib.h>
|
||
+#include <libxml/HTMLparser.h>
|
||
+#include <libgen.h>
|
||
+
|
||
+#include "ibusutil.h"
|
||
+
|
||
+typedef struct _EmojiData EmojiData;
|
||
+struct _EmojiData {
|
||
+ gchar *class;
|
||
+ gchar *emoji;
|
||
+ GSList *annotates;
|
||
+ GSList *prev_annotates;
|
||
+ GHashTable *dict;
|
||
+};
|
||
+
|
||
+const gchar *progname;
|
||
+
|
||
+static gboolean parse_node (xmlNode *node,
|
||
+ gboolean is_child,
|
||
+ const gchar *prop_name,
|
||
+ EmojiData *data);
|
||
+
|
||
+static void
|
||
+usage (void)
|
||
+{
|
||
+ g_print ("%s emoji-list.html emoji.dict\n", progname);
|
||
+}
|
||
+
|
||
+static void
|
||
+reset_emoji_element (EmojiData *data)
|
||
+{
|
||
+ g_clear_pointer (&data->class, g_free);
|
||
+ g_clear_pointer (&data->emoji, g_free);
|
||
+ if (data->annotates) {
|
||
+ g_slist_free_full (data->prev_annotates, g_free);
|
||
+ data->prev_annotates = data->annotates;
|
||
+ data->annotates = NULL;
|
||
+ }
|
||
+}
|
||
+
|
||
+static void
|
||
+free_dict_words (gpointer list)
|
||
+{
|
||
+ g_slist_free_full (list, g_free);
|
||
+}
|
||
+
|
||
+static gboolean
|
||
+parse_attr (xmlAttr *attr,
|
||
+ EmojiData *data)
|
||
+{
|
||
+ if (g_strcmp0 ((const gchar *) attr->name, "class") == 0 && attr->children)
|
||
+ parse_node (attr->children, TRUE, (const gchar *) attr->name, data);
|
||
+ if (g_strcmp0 ((const gchar *) attr->name, "target") == 0 && attr->children)
|
||
+ parse_node (attr->children, TRUE, (const gchar *) attr->name, data);
|
||
+ if (attr->next)
|
||
+ parse_attr (attr->next, data);
|
||
+ return TRUE;
|
||
+}
|
||
+
|
||
+static gboolean
|
||
+parse_node (xmlNode *node,
|
||
+ gboolean is_child,
|
||
+ const gchar *prop_name,
|
||
+ EmojiData *data)
|
||
+{
|
||
+ if (g_strcmp0 ((const gchar *) node->name, "tr") == 0) {
|
||
+ GSList *annotates = data->annotates;
|
||
+ while (annotates) {
|
||
+ GSList *emojis = g_hash_table_lookup (data->dict, annotates->data);
|
||
+ if (emojis) {
|
||
+ emojis = g_slist_copy_deep (emojis, (GCopyFunc) g_strdup, NULL);
|
||
+ }
|
||
+ emojis = g_slist_append (emojis, g_strdup (data->emoji));
|
||
+ g_hash_table_replace (data->dict,
|
||
+ g_strdup (annotates->data),
|
||
+ emojis);
|
||
+ annotates = annotates->next;
|
||
+ }
|
||
+ reset_emoji_element (data);
|
||
+ }
|
||
+ /* if node->name is "text" and is_child is FALSE,
|
||
+ * it's '\n' or Space between <td> and <td>.
|
||
+ */
|
||
+ if (g_strcmp0 ((const gchar *) node->name, "text") == 0 && is_child) {
|
||
+ /* Get "chars" in <td class="chars"> */
|
||
+ if (g_strcmp0 (prop_name, "class") == 0) {
|
||
+ if (g_strcmp0 (data->class, (const gchar *) node->content) != 0) {
|
||
+ g_clear_pointer (&data->class, g_free);
|
||
+ data->class = g_strdup ((const gchar *) node->content);
|
||
+ }
|
||
+ }
|
||
+ /* Get "annotate" in <td class="name"><a target="annotate"> */
|
||
+ if (g_strcmp0 (prop_name, "target") == 0 &&
|
||
+ g_strcmp0 (data->class, "name") == 0) {
|
||
+ g_clear_pointer (&data->class, g_free);
|
||
+ data->class = g_strdup ((const gchar *) node->content);
|
||
+ }
|
||
+ /* Get "emoji" in <td class="chars">emoji</td> */
|
||
+ if (g_strcmp0 (prop_name, "td") == 0 &&
|
||
+ g_strcmp0 (data->class, "chars") == 0) {
|
||
+ data->emoji = g_strdup ((const gchar *) node->content);
|
||
+ }
|
||
+ /* We ignore "NAME" for <td class="name">NAME</td> but
|
||
+ * takes "ANNOTATE" for
|
||
+ * <td class="name"><a target="annotate">ANNOTATE</a></td>
|
||
+ */
|
||
+ if (g_strcmp0 (prop_name, "td") == 0 &&
|
||
+ g_strcmp0 (data->class, "name") == 0) {
|
||
+ g_slist_free_full (data->annotates, g_free);
|
||
+ data->annotates = NULL;
|
||
+ }
|
||
+ /* Get "ANNOTATE" in
|
||
+ * <td class="name"><a target="annotate">ANNOTATE</a></td>
|
||
+ */
|
||
+ if (g_strcmp0 (prop_name, "a") == 0 &&
|
||
+ g_strcmp0 (data->class, "annotate") == 0) {
|
||
+ data->annotates =
|
||
+ g_slist_append (data->annotates,
|
||
+ g_strdup ((const gchar *) node->content));
|
||
+ }
|
||
+ }
|
||
+ /* Get "foo" in <td class="foo"> */
|
||
+ if (g_strcmp0 ((const gchar *) node->name, "td") == 0 &&
|
||
+ node->properties != NULL) {
|
||
+ parse_attr (node->properties, data);
|
||
+ }
|
||
+ /* Get "foo" in <a target="foo"> */
|
||
+ if (g_strcmp0 ((const gchar *) node->name, "a") == 0 &&
|
||
+ node->properties != NULL) {
|
||
+ parse_attr (node->properties, data);
|
||
+ }
|
||
+ if (node->children) {
|
||
+ parse_node (node->children, TRUE, (const gchar *) node->name, data);
|
||
+ } else {
|
||
+ /* If annotate is NULL likes <td class="name"></td>,
|
||
+ * the previous emoji cell has the same annotate.
|
||
+ */
|
||
+ if (g_strcmp0 ((const gchar *) node->name, "td") == 0 &&
|
||
+ g_strcmp0 (data->class, "name") == 0) {
|
||
+ data->annotates = g_slist_copy_deep (data->prev_annotates,
|
||
+ (GCopyFunc) g_strdup,
|
||
+ NULL);
|
||
+ }
|
||
+ }
|
||
+ if (node->next)
|
||
+ parse_node (node->next, FALSE, (const gchar *) node->name, data);
|
||
+
|
||
+ return TRUE;
|
||
+}
|
||
+
|
||
+static GHashTable *
|
||
+parse_html (const gchar *filename)
|
||
+{
|
||
+ xmlDoc *doc = htmlParseFile (filename, "utf-8");
|
||
+ EmojiData data = { 0, };
|
||
+
|
||
+ if (doc == NULL || doc->children == NULL) {
|
||
+ g_warning ("Parse Error in document type: %x",
|
||
+ doc ? doc->type : 0);
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
+ data.dict = g_hash_table_new_full (g_str_hash,
|
||
+ g_str_equal,
|
||
+ g_free,
|
||
+ free_dict_words);
|
||
+ parse_node (doc->children, TRUE, (const gchar *) doc->name, &data);
|
||
+
|
||
+ reset_emoji_element (&data);
|
||
+ g_slist_free_full (data.prev_annotates, g_free);
|
||
+
|
||
+ return data.dict;
|
||
+}
|
||
+
|
||
+int
|
||
+main (int argc, char *argv[])
|
||
+{
|
||
+ GHashTable *dict;
|
||
+ progname = basename (argv[0]);
|
||
+
|
||
+ if (argc < 3) {
|
||
+ usage ();
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
+ dict = parse_html (argv[1]);
|
||
+ ibus_emoji_dict_save (argv[2], dict);
|
||
+ g_hash_table_destroy (dict);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
diff --git a/src/ibusenginesimple.c b/src/ibusenginesimple.c
|
||
index 1b688b0..8efe5a9 100644
|
||
--- a/src/ibusenginesimple.c
|
||
+++ b/src/ibusenginesimple.c
|
||
@@ -3,7 +3,7 @@
|
||
/* ibus - The Input Bus
|
||
* Copyright (C) 2014 Peng Huang <shawn.p.huang@gmail.com>
|
||
* Copyright (C) 2015-2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
||
- * Copyright (C) 2014 Red Hat, Inc.
|
||
+ * Copyright (C) 2014-2016 Red Hat, Inc.
|
||
*
|
||
* This library is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU Lesser General Public
|
||
@@ -31,6 +31,7 @@
|
||
|
||
#include "ibuskeys.h"
|
||
#include "ibuskeysyms.h"
|
||
+#include "ibusutil.h"
|
||
|
||
/* This file contains the table of the compose sequences,
|
||
* static const guint16 gtk_compose_seqs_compact[] = {}
|
||
@@ -42,16 +43,27 @@
|
||
#include <stdlib.h>
|
||
|
||
#define X11_DATADIR X11_DATA_PREFIX "/share/X11/locale"
|
||
+#define EMOJI_SOURCE_LEN 100
|
||
#define IBUS_ENGINE_SIMPLE_GET_PRIVATE(o) \
|
||
(G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_ENGINE_SIMPLE, IBusEngineSimplePrivate))
|
||
|
||
-struct _IBusEngineSimplePrivate {
|
||
- guint16 compose_buffer[IBUS_MAX_COMPOSE_LEN + 1];
|
||
- gunichar tentative_match;
|
||
- gint tentative_match_len;
|
||
+typedef struct {
|
||
+ GHashTable *dict;
|
||
+ int max_seq_len;
|
||
+} IBusEngineDict;
|
||
|
||
- guint in_hex_sequence : 1;
|
||
- guint modifiers_dropped : 1;
|
||
+struct _IBusEngineSimplePrivate {
|
||
+ guint16 compose_buffer[EMOJI_SOURCE_LEN];
|
||
+ gunichar tentative_match;
|
||
+ gchar *tentative_emoji;
|
||
+ gint tentative_match_len;
|
||
+
|
||
+ guint in_hex_sequence : 1;
|
||
+ guint in_emoji_sequence : 1;
|
||
+ guint modifiers_dropped : 1;
|
||
+ IBusEngineDict *emoji_dict;
|
||
+ IBusLookupTable *lookup_table;
|
||
+ gboolean lookup_table_visible;
|
||
};
|
||
|
||
/* From the values below, the value 30 means the number of different first keysyms
|
||
@@ -97,6 +109,8 @@ static gboolean ibus_engine_simple_process_key_event
|
||
guint modifiers);
|
||
static void ibus_engine_simple_commit_char (IBusEngineSimple *simple,
|
||
gunichar ch);
|
||
+static void ibus_engine_simple_commit_str (IBusEngineSimple *simple,
|
||
+ const gchar *str);
|
||
static void ibus_engine_simple_update_preedit_text
|
||
(IBusEngineSimple *simple);
|
||
|
||
@@ -128,6 +142,18 @@ ibus_engine_simple_init (IBusEngineSimple *simple)
|
||
static void
|
||
ibus_engine_simple_destroy (IBusEngineSimple *simple)
|
||
{
|
||
+ IBusEngineSimplePrivate *priv = simple->priv;
|
||
+
|
||
+ if (priv->emoji_dict) {
|
||
+ if (priv->emoji_dict->dict)
|
||
+ g_clear_pointer (&priv->emoji_dict->dict, g_hash_table_destroy);
|
||
+ g_slice_free (IBusEngineDict, priv->emoji_dict);
|
||
+ priv->emoji_dict = NULL;
|
||
+ }
|
||
+
|
||
+ g_clear_pointer (&priv->lookup_table, g_object_unref);
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+
|
||
IBUS_OBJECT_CLASS(ibus_engine_simple_parent_class)->destroy (
|
||
IBUS_OBJECT (simple));
|
||
}
|
||
@@ -146,6 +172,11 @@ ibus_engine_simple_reset (IBusEngine *engine)
|
||
priv->tentative_match_len = 0;
|
||
ibus_engine_hide_preedit_text ((IBusEngine *)simple);
|
||
}
|
||
+ if (priv->tentative_emoji || priv->in_emoji_sequence) {
|
||
+ priv->in_emoji_sequence = FALSE;
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+ ibus_engine_hide_preedit_text ((IBusEngine *)simple);
|
||
+ }
|
||
}
|
||
|
||
static void
|
||
@@ -162,23 +193,60 @@ ibus_engine_simple_commit_char (IBusEngineSimple *simple,
|
||
priv->tentative_match_len = 0;
|
||
ibus_engine_simple_update_preedit_text (simple);
|
||
}
|
||
+ if (priv->tentative_emoji || priv->in_emoji_sequence) {
|
||
+ priv->in_emoji_sequence = FALSE;
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+ ibus_engine_simple_update_preedit_text (simple);
|
||
+ }
|
||
|
||
ibus_engine_commit_text ((IBusEngine *)simple,
|
||
ibus_text_new_from_unichar (ch));
|
||
}
|
||
|
||
static void
|
||
+ibus_engine_simple_commit_str (IBusEngineSimple *simple,
|
||
+ const gchar *str)
|
||
+{
|
||
+ IBusEngineSimplePrivate *priv = simple->priv;
|
||
+ gchar *backup_str;
|
||
+
|
||
+ g_return_if_fail (str && *str);
|
||
+
|
||
+ backup_str = g_strdup (str);
|
||
+
|
||
+ if (priv->tentative_match || priv->in_hex_sequence) {
|
||
+ priv->in_hex_sequence = FALSE;
|
||
+ priv->tentative_match = 0;
|
||
+ priv->tentative_match_len = 0;
|
||
+ ibus_engine_simple_update_preedit_text (simple);
|
||
+ }
|
||
+ if (priv->tentative_emoji || priv->in_emoji_sequence) {
|
||
+ priv->in_emoji_sequence = FALSE;
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+ ibus_engine_simple_update_preedit_text (simple);
|
||
+ }
|
||
+
|
||
+ ibus_engine_commit_text ((IBusEngine *)simple,
|
||
+ ibus_text_new_from_string (backup_str));
|
||
+ g_free (backup_str);
|
||
+}
|
||
+
|
||
+static void
|
||
ibus_engine_simple_update_preedit_text (IBusEngineSimple *simple)
|
||
{
|
||
IBusEngineSimplePrivate *priv = simple->priv;
|
||
|
||
- gunichar outbuf[IBUS_MAX_COMPOSE_LEN + 2];
|
||
+ gunichar outbuf[EMOJI_SOURCE_LEN + 1];
|
||
int len = 0;
|
||
|
||
- if (priv->in_hex_sequence) {
|
||
+ if (priv->in_hex_sequence || priv->in_emoji_sequence) {
|
||
int hexchars = 0;
|
||
|
||
- outbuf[0] = L'u';
|
||
+ if (priv->in_hex_sequence)
|
||
+ outbuf[0] = L'u';
|
||
+ else
|
||
+ outbuf[0] = L'@';
|
||
+
|
||
len = 1;
|
||
|
||
while (priv->compose_buffer[hexchars] != 0) {
|
||
@@ -187,10 +255,22 @@ ibus_engine_simple_update_preedit_text (IBusEngineSimple *simple)
|
||
++len;
|
||
++hexchars;
|
||
}
|
||
- g_assert (len <= IBUS_MAX_COMPOSE_LEN + 1);
|
||
+
|
||
+ if (priv->in_hex_sequence)
|
||
+ g_assert (len <= IBUS_MAX_COMPOSE_LEN + 1);
|
||
+ else
|
||
+ g_assert (len <= EMOJI_SOURCE_LEN + 1);
|
||
}
|
||
- else if (priv->tentative_match)
|
||
+ else if (priv->tentative_match) {
|
||
outbuf[len++] = priv->tentative_match;
|
||
+ } else if (priv->tentative_emoji && *priv->tentative_emoji) {
|
||
+ IBusText *text = ibus_text_new_from_string (priv->tentative_emoji);
|
||
+ len = strlen (priv->tentative_emoji);
|
||
+ ibus_text_append_attribute (text,
|
||
+ IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, len);
|
||
+ ibus_engine_update_preedit_text ((IBusEngine *)simple, text, len, TRUE);
|
||
+ return;
|
||
+ }
|
||
|
||
outbuf[len] = L'\0';
|
||
if (len == 0) {
|
||
@@ -277,6 +357,104 @@ check_hex (IBusEngineSimple *simple,
|
||
return TRUE;
|
||
}
|
||
|
||
+static IBusEngineDict *
|
||
+load_emoji_dict ()
|
||
+{
|
||
+ IBusEngineDict *emoji_dict;
|
||
+ GList *keys;
|
||
+ int max_length = 0;
|
||
+
|
||
+ emoji_dict = g_slice_new0 (IBusEngineDict);
|
||
+ emoji_dict->dict = ibus_emoji_dict_load (IBUS_DATA_DIR "/dicts/emoji.dict");
|
||
+ if (!emoji_dict->dict)
|
||
+ return emoji_dict;
|
||
+
|
||
+ keys = g_hash_table_get_keys (emoji_dict->dict);
|
||
+ for (; keys; keys = keys->next) {
|
||
+ int length = strlen (keys->data);
|
||
+ if (max_length < length)
|
||
+ max_length = length;
|
||
+ }
|
||
+ emoji_dict->max_seq_len = max_length;
|
||
+
|
||
+ return emoji_dict;
|
||
+}
|
||
+
|
||
+static gboolean
|
||
+check_emoji_table (IBusEngineSimple *simple,
|
||
+ gint n_compose,
|
||
+ gint index)
|
||
+{
|
||
+ IBusEngineSimplePrivate *priv = simple->priv;
|
||
+ IBusEngineDict *emoji_dict = priv->emoji_dict;
|
||
+ GString *str = NULL;
|
||
+ gint i;
|
||
+ gchar buf[7];
|
||
+ GSList *words = NULL;
|
||
+
|
||
+ g_assert (IBUS_IS_ENGINE_SIMPLE (simple));
|
||
+
|
||
+ if (priv->lookup_table == NULL) {
|
||
+ priv->lookup_table = ibus_lookup_table_new (10, 0, TRUE, TRUE);
|
||
+ g_object_ref_sink (priv->lookup_table);
|
||
+ }
|
||
+ if (emoji_dict == NULL)
|
||
+ emoji_dict = priv->emoji_dict = load_emoji_dict (simple);
|
||
+
|
||
+ if (emoji_dict == NULL || emoji_dict->dict == NULL)
|
||
+ return FALSE;
|
||
+
|
||
+ if (n_compose > emoji_dict->max_seq_len)
|
||
+ return FALSE;
|
||
+
|
||
+ str = g_string_new (NULL);
|
||
+ priv->lookup_table_visible = FALSE;
|
||
+
|
||
+ i = 0;
|
||
+ while (i < n_compose) {
|
||
+ gunichar ch;
|
||
+
|
||
+ ch = ibus_keyval_to_unicode (priv->compose_buffer[i]);
|
||
+
|
||
+ if (ch == 0)
|
||
+ return FALSE;
|
||
+
|
||
+ if (!g_unichar_isprint (ch))
|
||
+ return FALSE;
|
||
+
|
||
+ buf[g_unichar_to_utf8 (ch, buf)] = '\0';
|
||
+
|
||
+ g_string_append (str, buf);
|
||
+
|
||
+ ++i;
|
||
+ }
|
||
+
|
||
+ if (str->str) {
|
||
+ words = g_hash_table_lookup (emoji_dict->dict, str->str);
|
||
+ }
|
||
+ g_string_free (str, TRUE);
|
||
+
|
||
+ if (words != NULL) {
|
||
+ int i = 0;
|
||
+ ibus_lookup_table_clear (priv->lookup_table);
|
||
+ priv->lookup_table_visible = TRUE;
|
||
+
|
||
+ while (words) {
|
||
+ if (i == index) {
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+ priv->tentative_emoji = g_strdup (words->data);
|
||
+ }
|
||
+ IBusText *text = ibus_text_new_from_string (words->data);
|
||
+ ibus_lookup_table_append_candidate (priv->lookup_table, text);
|
||
+ words = words->next;
|
||
+ i++;
|
||
+ }
|
||
+ return TRUE;
|
||
+ }
|
||
+
|
||
+ return FALSE;
|
||
+}
|
||
+
|
||
static int
|
||
compare_seq_index (const void *key, const void *value)
|
||
{
|
||
@@ -626,10 +804,10 @@ ibus_check_algorithmically (const guint16 *compose_buffer,
|
||
|
||
static gboolean
|
||
no_sequence_matches (IBusEngineSimple *simple,
|
||
- gint n_compose,
|
||
- guint keyval,
|
||
- guint keycode,
|
||
- guint modifiers)
|
||
+ gint n_compose,
|
||
+ guint keyval,
|
||
+ guint keycode,
|
||
+ guint modifiers)
|
||
{
|
||
IBusEngineSimplePrivate *priv = simple->priv;
|
||
|
||
@@ -642,8 +820,7 @@ no_sequence_matches (IBusEngineSimple *simple,
|
||
gint len = priv->tentative_match_len;
|
||
int i;
|
||
|
||
- ibus_engine_simple_commit_char (simple,
|
||
- priv->tentative_match);
|
||
+ ibus_engine_simple_commit_char (simple, priv->tentative_match);
|
||
priv->compose_buffer[0] = 0;
|
||
|
||
for (i=0; i < n_compose - len - 1; i++) {
|
||
@@ -655,8 +832,11 @@ no_sequence_matches (IBusEngineSimple *simple,
|
||
|
||
return ibus_engine_simple_process_key_event (
|
||
(IBusEngine *)simple, keyval, keycode, modifiers);
|
||
- }
|
||
- else {
|
||
+ } else if (priv->tentative_emoji && *priv->tentative_emoji) {
|
||
+ ibus_engine_simple_commit_str (simple, priv->tentative_emoji);
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+ priv->compose_buffer[0] = 0;
|
||
+ } else {
|
||
priv->compose_buffer[0] = 0;
|
||
if (n_compose > 1) {
|
||
/* Invalid sequence */
|
||
@@ -676,6 +856,7 @@ no_sequence_matches (IBusEngineSimple *simple,
|
||
else
|
||
return FALSE;
|
||
}
|
||
+ return FALSE;
|
||
}
|
||
|
||
static gboolean
|
||
@@ -687,6 +868,39 @@ is_hex_keyval (guint keyval)
|
||
}
|
||
|
||
static gboolean
|
||
+is_graph_keyval (guint keyval)
|
||
+{
|
||
+ gunichar ch = ibus_keyval_to_unicode (keyval);
|
||
+
|
||
+ return g_unichar_isgraph (ch);
|
||
+}
|
||
+
|
||
+static void
|
||
+ibus_engine_simple_update_lookup_and_aux_table (IBusEngineSimple *simple)
|
||
+{
|
||
+ IBusEngineSimplePrivate *priv;
|
||
+ guint index, candidates;
|
||
+ gchar *aux_label = NULL;
|
||
+ IBusText *text = NULL;
|
||
+
|
||
+ g_return_if_fail (IBUS_IS_ENGINE_SIMPLE (simple));
|
||
+
|
||
+ priv = simple->priv;
|
||
+ index = ibus_lookup_table_get_cursor_pos (priv->lookup_table) + 1;
|
||
+ candidates = ibus_lookup_table_get_number_of_candidates(priv->lookup_table);
|
||
+ aux_label = g_strdup_printf ("(%u / %u)", index, candidates);
|
||
+ text = ibus_text_new_from_string (aux_label);
|
||
+ g_free (aux_label);
|
||
+
|
||
+ ibus_engine_update_auxiliary_text (IBUS_ENGINE (simple),
|
||
+ text,
|
||
+ priv->lookup_table_visible);
|
||
+ ibus_engine_update_lookup_table (IBUS_ENGINE (simple),
|
||
+ priv->lookup_table,
|
||
+ priv->lookup_table_visible);
|
||
+}
|
||
+
|
||
+static gboolean
|
||
ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
guint keyval,
|
||
guint keycode,
|
||
@@ -697,10 +911,13 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
gint n_compose = 0;
|
||
gboolean have_hex_mods;
|
||
gboolean is_hex_start;
|
||
+ gboolean is_emoji_start = FALSE;
|
||
gboolean is_hex_end;
|
||
+ gboolean is_space;
|
||
gboolean is_backspace;
|
||
gboolean is_escape;
|
||
guint hex_keyval;
|
||
+ guint printable_keyval;
|
||
gint i;
|
||
gboolean compose_finish;
|
||
gunichar output_char;
|
||
@@ -714,17 +931,16 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
keyval == IBUS_KEY_Shift_L || keyval == IBUS_KEY_Shift_R)) {
|
||
if (priv->tentative_match &&
|
||
g_unichar_validate (priv->tentative_match)) {
|
||
- ibus_engine_simple_commit_char (simple,
|
||
- priv->tentative_match);
|
||
- }
|
||
- else if (n_compose == 0) {
|
||
+ ibus_engine_simple_commit_char (simple, priv->tentative_match);
|
||
+ } else if (n_compose == 0) {
|
||
priv->modifiers_dropped = TRUE;
|
||
- }
|
||
- else {
|
||
+ } else {
|
||
/* invalid hex sequence */
|
||
/* FIXME beep_window (event->window); */
|
||
priv->tentative_match = 0;
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
priv->in_hex_sequence = FALSE;
|
||
+ priv->in_emoji_sequence = FALSE;
|
||
priv->compose_buffer[0] = 0;
|
||
|
||
ibus_engine_simple_update_preedit_text (simple);
|
||
@@ -732,6 +948,26 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
|
||
return TRUE;
|
||
}
|
||
+ /* Handle Shift + Space */
|
||
+ else if (priv->in_emoji_sequence &&
|
||
+ (keyval == IBUS_KEY_Control_L || keyval == IBUS_KEY_Control_R)) {
|
||
+ if (priv->tentative_emoji && *priv->tentative_emoji) {
|
||
+ ibus_engine_simple_commit_str (simple, priv->tentative_emoji);
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+ } else if (n_compose == 0) {
|
||
+ priv->modifiers_dropped = TRUE;
|
||
+ } else {
|
||
+ /* invalid hex sequence */
|
||
+ /* FIXME beep_window (event->window); */
|
||
+ priv->tentative_match = 0;
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+ priv->in_hex_sequence = FALSE;
|
||
+ priv->in_emoji_sequence = FALSE;
|
||
+ priv->compose_buffer[0] = 0;
|
||
+
|
||
+ ibus_engine_simple_update_preedit_text (simple);
|
||
+ }
|
||
+ }
|
||
else
|
||
return FALSE;
|
||
}
|
||
@@ -741,25 +977,33 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
if (keyval == ibus_compose_ignore[i])
|
||
return FALSE;
|
||
|
||
- if (priv->in_hex_sequence && priv->modifiers_dropped)
|
||
+ if ((priv->in_hex_sequence || priv->in_emoji_sequence)
|
||
+ && priv->modifiers_dropped) {
|
||
have_hex_mods = TRUE;
|
||
- else
|
||
+ } else {
|
||
have_hex_mods = (modifiers & (HEX_MOD_MASK)) == HEX_MOD_MASK;
|
||
+ }
|
||
|
||
is_hex_start = keyval == IBUS_KEY_U;
|
||
+#ifdef ENABLE_EMOJI_DICT
|
||
+ is_emoji_start = keyval == IBUS_KEY_E;
|
||
+#endif
|
||
is_hex_end = (keyval == IBUS_KEY_space ||
|
||
keyval == IBUS_KEY_KP_Space ||
|
||
keyval == IBUS_KEY_Return ||
|
||
keyval == IBUS_KEY_ISO_Enter ||
|
||
keyval == IBUS_KEY_KP_Enter);
|
||
+ is_space = (keyval == IBUS_KEY_space || keyval == IBUS_KEY_KP_Space);
|
||
is_backspace = keyval == IBUS_KEY_BackSpace;
|
||
is_escape = keyval == IBUS_KEY_Escape;
|
||
hex_keyval = is_hex_keyval (keyval) ? keyval : 0;
|
||
+ printable_keyval = is_graph_keyval (keyval) ? keyval : 0;
|
||
|
||
/* gtkimcontextsimple causes a buffer overflow in priv->compose_buffer.
|
||
* Add the check code here.
|
||
*/
|
||
- if (n_compose >= IBUS_MAX_COMPOSE_LEN) {
|
||
+ if ((n_compose >= IBUS_MAX_COMPOSE_LEN && priv->in_hex_sequence) ||
|
||
+ (n_compose >= EMOJI_SOURCE_LEN && priv->in_emoji_sequence)) {
|
||
if (is_backspace) {
|
||
priv->compose_buffer[--n_compose] = 0;
|
||
}
|
||
@@ -767,7 +1011,9 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
/* invalid hex sequence */
|
||
// beep_window (event->window);
|
||
priv->tentative_match = 0;
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
priv->in_hex_sequence = FALSE;
|
||
+ priv->in_emoji_sequence = FALSE;
|
||
priv->compose_buffer[0] = 0;
|
||
}
|
||
else if (is_escape) {
|
||
@@ -789,12 +1035,16 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
* ISO_Level3_Switch.
|
||
*/
|
||
if (!have_hex_mods ||
|
||
- (n_compose > 0 && !priv->in_hex_sequence) ||
|
||
- (n_compose == 0 && !priv->in_hex_sequence && !is_hex_start) ||
|
||
+ (n_compose > 0 && !priv->in_hex_sequence && !priv->in_emoji_sequence) ||
|
||
+ (n_compose == 0 && !priv->in_hex_sequence && !is_hex_start &&
|
||
+ !priv->in_emoji_sequence && !is_emoji_start) ||
|
||
(priv->in_hex_sequence && !hex_keyval &&
|
||
- !is_hex_start && !is_hex_end && !is_escape && !is_backspace)) {
|
||
+ !is_hex_start && !is_hex_end && !is_escape && !is_backspace) ||
|
||
+ (priv->in_emoji_sequence && !printable_keyval &&
|
||
+ !is_emoji_start && !is_hex_end && !is_escape && !is_backspace)) {
|
||
if (modifiers & (IBUS_MOD1_MASK | IBUS_CONTROL_MASK) ||
|
||
- (priv->in_hex_sequence && priv->modifiers_dropped &&
|
||
+ ((priv->in_hex_sequence || priv->in_emoji_sequence) &&
|
||
+ priv->modifiers_dropped &&
|
||
(keyval == IBUS_KEY_Return ||
|
||
keyval == IBUS_KEY_ISO_Enter ||
|
||
keyval == IBUS_KEY_KP_Enter))) {
|
||
@@ -816,6 +1066,20 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
|
||
return TRUE;
|
||
}
|
||
+ if (priv->in_emoji_sequence && have_hex_mods && is_backspace) {
|
||
+ if (n_compose > 0) {
|
||
+ n_compose--;
|
||
+ priv->compose_buffer[n_compose] = 0;
|
||
+ check_emoji_table (simple, n_compose, -1);
|
||
+ ibus_engine_simple_update_lookup_and_aux_table (simple);
|
||
+ } else {
|
||
+ priv->in_emoji_sequence = FALSE;
|
||
+ }
|
||
+
|
||
+ ibus_engine_simple_update_preedit_text (simple);
|
||
+
|
||
+ return TRUE;
|
||
+ }
|
||
|
||
/* Check for hex sequence restart */
|
||
if (priv->in_hex_sequence && have_hex_mods && is_hex_start) {
|
||
@@ -833,13 +1097,41 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
}
|
||
}
|
||
}
|
||
+ if (priv->in_emoji_sequence && have_hex_mods && is_emoji_start) {
|
||
+ if (priv->tentative_emoji && *priv->tentative_emoji) {
|
||
+ ibus_engine_simple_commit_str (simple, priv->tentative_emoji);
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+ }
|
||
+ else {
|
||
+ if (n_compose > 0) {
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+ priv->in_emoji_sequence = FALSE;
|
||
+ priv->compose_buffer[0] = 0;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
|
||
/* Check for hex sequence start */
|
||
if (!priv->in_hex_sequence && have_hex_mods && is_hex_start) {
|
||
priv->compose_buffer[0] = 0;
|
||
priv->in_hex_sequence = TRUE;
|
||
+ priv->in_emoji_sequence = FALSE;
|
||
priv->modifiers_dropped = FALSE;
|
||
priv->tentative_match = 0;
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+
|
||
+ // g_debug ("Start HEX MODE");
|
||
+
|
||
+ ibus_engine_simple_update_preedit_text (simple);
|
||
+
|
||
+ return TRUE;
|
||
+ } else if (!priv->in_emoji_sequence && have_hex_mods && is_emoji_start) {
|
||
+ priv->compose_buffer[0] = 0;
|
||
+ priv->in_hex_sequence = FALSE;
|
||
+ priv->in_emoji_sequence = TRUE;
|
||
+ priv->modifiers_dropped = FALSE;
|
||
+ priv->tentative_match = 0;
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
|
||
// g_debug ("Start HEX MODE");
|
||
|
||
@@ -864,9 +1156,20 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
// beep_window (event->window);
|
||
return TRUE;
|
||
}
|
||
- }
|
||
- else
|
||
+ } else if (priv->in_emoji_sequence) {
|
||
+ if (printable_keyval) {
|
||
+ priv->compose_buffer[n_compose++] = printable_keyval;
|
||
+ }
|
||
+ else if (is_space && (modifiers & IBUS_SHIFT_MASK)) {
|
||
+ priv->compose_buffer[n_compose++] = IBUS_KEY_space;
|
||
+ }
|
||
+ else if (is_escape) {
|
||
+ ibus_engine_simple_reset (engine);
|
||
+ return TRUE;
|
||
+ }
|
||
+ } else {
|
||
priv->compose_buffer[n_compose++] = keyval;
|
||
+ }
|
||
|
||
priv->compose_buffer[n_compose] = 0;
|
||
|
||
@@ -880,8 +1183,7 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
ibus_engine_simple_commit_char (simple,
|
||
priv->tentative_match);
|
||
priv->compose_buffer[0] = 0;
|
||
- }
|
||
- else {
|
||
+ } else {
|
||
// FIXME
|
||
/* invalid hex sequence */
|
||
// beep_window (event->window);
|
||
@@ -899,6 +1201,73 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
|
||
return TRUE;
|
||
}
|
||
}
|
||
+ else if (priv->in_emoji_sequence) {
|
||
+ if (have_hex_mods && n_compose > 0) {
|
||
+ gboolean update_lookup_table = FALSE;
|
||
+
|
||
+ if (priv->lookup_table_visible) {
|
||
+ switch (keyval) {
|
||
+ case IBUS_KEY_space:
|
||
+ case IBUS_KEY_KP_Space:
|
||
+ if ((modifiers & IBUS_SHIFT_MASK) == 0) {
|
||
+ ibus_lookup_table_cursor_down (priv->lookup_table);
|
||
+ update_lookup_table = TRUE;
|
||
+ }
|
||
+ break;
|
||
+ case IBUS_KEY_Down:
|
||
+ ibus_lookup_table_cursor_down (priv->lookup_table);
|
||
+ update_lookup_table = TRUE;
|
||
+ break;
|
||
+ case IBUS_KEY_Up:
|
||
+ ibus_lookup_table_cursor_up (priv->lookup_table);
|
||
+ update_lookup_table = TRUE;
|
||
+ break;
|
||
+ case IBUS_KEY_Page_Down:
|
||
+ ibus_lookup_table_page_down (priv->lookup_table);
|
||
+ update_lookup_table = TRUE;
|
||
+ break;
|
||
+ case IBUS_KEY_Page_Up:
|
||
+ ibus_lookup_table_page_up (priv->lookup_table);
|
||
+ update_lookup_table = TRUE;
|
||
+ break;
|
||
+ default:;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ if (!update_lookup_table) {
|
||
+ if (is_hex_end && !is_space) {
|
||
+ if (priv->lookup_table) {
|
||
+ int index = (int) ibus_lookup_table_get_cursor_pos (
|
||
+ priv->lookup_table);
|
||
+ check_emoji_table (simple, n_compose, index);
|
||
+ priv->lookup_table_visible = FALSE;
|
||
+ update_lookup_table = TRUE;
|
||
+ }
|
||
+ }
|
||
+ else if (check_emoji_table (simple, n_compose, -1)) {
|
||
+ update_lookup_table = TRUE;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ if (update_lookup_table)
|
||
+ ibus_engine_simple_update_lookup_and_aux_table (simple);
|
||
+ if (is_hex_end && !is_space) {
|
||
+ if (priv->tentative_emoji && *priv->tentative_emoji) {
|
||
+ ibus_engine_simple_commit_str (simple,
|
||
+ priv->tentative_emoji);
|
||
+ priv->compose_buffer[0] = 0;
|
||
+ } else {
|
||
+ g_clear_pointer (&priv->tentative_emoji, g_free);
|
||
+ priv->in_emoji_sequence = FALSE;
|
||
+ priv->compose_buffer[0] = 0;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ ibus_engine_simple_update_preedit_text (simple);
|
||
+
|
||
+ return TRUE;
|
||
+ }
|
||
+ }
|
||
else {
|
||
GSList *list = global_tables;
|
||
while (list) {
|
||
diff --git a/src/ibusutil.c b/src/ibusutil.c
|
||
index b9f3fdd..bfaa4f4 100644
|
||
--- a/src/ibusutil.c
|
||
+++ b/src/ibusutil.c
|
||
@@ -2,8 +2,8 @@
|
||
/* vim:set et sts=4: */
|
||
/* bus - The Input Bus
|
||
* Copyright (C) 2008-2015 Peng Huang <shawn.p.huang@gmail.com>
|
||
- * Copyright (C) 2010-2015 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
||
- * Copyright (C) 2008-2015 Red Hat, Inc.
|
||
+ * Copyright (C) 2010-2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
||
+ * Copyright (C) 2008-2016 Red Hat, Inc.
|
||
*
|
||
* This library is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU Lesser General Public
|
||
@@ -34,6 +34,9 @@
|
||
#include <libintl.h>
|
||
#endif
|
||
|
||
+#define IBUS_DICT_MAGIC "IBusDict"
|
||
+#define IBUS_DICT_VERSION (1)
|
||
+
|
||
/* gettext macro */
|
||
#define N_(t) t
|
||
|
||
@@ -125,6 +128,74 @@ _load_lang()
|
||
ibus_xml_free (node);
|
||
}
|
||
|
||
+static void
|
||
+free_dict_words (gpointer list)
|
||
+{
|
||
+ g_slist_free_full (list, g_free);
|
||
+}
|
||
+
|
||
+static void
|
||
+variant_foreach_add_emoji (gchar *annotation,
|
||
+ GSList *emojis,
|
||
+ GVariantBuilder *builder)
|
||
+{
|
||
+ int i;
|
||
+ int length = (int) g_slist_length (emojis);
|
||
+ gchar **buff = g_new0 (gchar *, length);
|
||
+ GSList *l = emojis;
|
||
+
|
||
+ for (i = 0; i < length; i++, l = l->next)
|
||
+ buff[i] = (gchar *) l->data;
|
||
+
|
||
+ g_variant_builder_add (builder,
|
||
+ "{sv}",
|
||
+ annotation,
|
||
+ g_variant_new_strv ((const gchar * const *) buff,
|
||
+ length));
|
||
+ g_free (buff);
|
||
+}
|
||
+
|
||
+static GVariant *
|
||
+ibus_emoji_dict_serialize (GHashTable *dict)
|
||
+{
|
||
+ GVariantBuilder builder;
|
||
+
|
||
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
||
+ g_hash_table_foreach (dict, (GHFunc) variant_foreach_add_emoji, &builder);
|
||
+ return g_variant_builder_end (&builder);
|
||
+}
|
||
+
|
||
+static GHashTable *
|
||
+ibus_emoji_dict_deserialize (GVariant *variant)
|
||
+{
|
||
+ GHashTable *dict = NULL;
|
||
+ GVariantIter iter;
|
||
+ gchar *annotate = NULL;
|
||
+ GVariant *emojis_variant = NULL;
|
||
+
|
||
+ dict = g_hash_table_new_full (g_str_hash,
|
||
+ g_str_equal,
|
||
+ g_free,
|
||
+ free_dict_words);
|
||
+
|
||
+ g_variant_iter_init (&iter, variant);
|
||
+ while (g_variant_iter_loop (&iter, "{sv}", &annotate, &emojis_variant)) {
|
||
+ gsize i;
|
||
+ gsize length = 0;
|
||
+ const gchar **array = g_variant_get_strv (emojis_variant, &length);
|
||
+ GSList *emojis = NULL;
|
||
+
|
||
+ for (i = 0; i < length; i++) {
|
||
+ emojis = g_slist_append (emojis, g_strdup (array[i]));
|
||
+ }
|
||
+ g_hash_table_insert (dict, annotate, emojis);
|
||
+ annotate = NULL;
|
||
+ g_clear_pointer (&emojis_variant, g_variant_unref);
|
||
+ }
|
||
+
|
||
+ return dict;
|
||
+}
|
||
+
|
||
const gchar *
|
||
ibus_get_untranslated_language_name (const gchar *_locale)
|
||
{
|
||
@@ -171,3 +242,121 @@ ibus_g_variant_get_child_string (GVariant *variant, gsize index, char **str)
|
||
g_free (*str);
|
||
g_variant_get_child (variant, index, "s", str);
|
||
}
|
||
+
|
||
+void
|
||
+ibus_emoji_dict_save (const gchar *path, GHashTable *dict)
|
||
+{
|
||
+ GVariant *variant;
|
||
+ const gchar *header = IBUS_DICT_MAGIC;
|
||
+ const guint16 version = IBUS_DICT_VERSION;
|
||
+ const gchar *contents;
|
||
+ gsize length;
|
||
+ GError *error = NULL;
|
||
+
|
||
+ variant = g_variant_new ("(sqv)",
|
||
+ header,
|
||
+ version,
|
||
+ ibus_emoji_dict_serialize (dict));
|
||
+
|
||
+ contents = g_variant_get_data (variant);
|
||
+ length = g_variant_get_size (variant);
|
||
+
|
||
+ if (!g_file_set_contents (path, contents, length, &error)) {
|
||
+ g_warning ("Failed to save emoji dict %s: %s", path, error->message);
|
||
+ g_error_free (error);
|
||
+ }
|
||
+
|
||
+ g_variant_unref (variant);
|
||
+}
|
||
+
|
||
+GHashTable *
|
||
+ibus_emoji_dict_load (const gchar *path)
|
||
+{
|
||
+ gchar *contents = NULL;
|
||
+ gsize length = 0;
|
||
+ GError *error = NULL;
|
||
+ GVariant *variant_table = NULL;
|
||
+ GVariant *variant = NULL;
|
||
+ const gchar *header = NULL;
|
||
+ guint16 version = 0;
|
||
+ GHashTable *retval = NULL;
|
||
+
|
||
+ if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
|
||
+ g_warning ("Emoji dict does not exist: %s", path);
|
||
+ goto out_load_cache;
|
||
+ }
|
||
+
|
||
+ if (!g_file_get_contents (path, &contents, &length, &error)) {
|
||
+ g_warning ("Failed to get dict content %s: %s", path, error->message);
|
||
+ g_error_free (error);
|
||
+ goto out_load_cache;
|
||
+ }
|
||
+
|
||
+ variant_table = g_variant_new_from_data (G_VARIANT_TYPE ("(sq)"),
|
||
+ contents,
|
||
+ length,
|
||
+ FALSE,
|
||
+ NULL,
|
||
+ NULL);
|
||
+
|
||
+ if (variant_table == NULL) {
|
||
+ g_warning ("cache table is broken.");
|
||
+ goto out_load_cache;
|
||
+ }
|
||
+
|
||
+ g_variant_get (variant_table, "(&sq)", &header, &version);
|
||
+
|
||
+ if (g_strcmp0 (header, IBUS_DICT_MAGIC) != 0) {
|
||
+ g_warning ("cache is not IBusDict.");
|
||
+ goto out_load_cache;
|
||
+ }
|
||
+
|
||
+ if (version != IBUS_DICT_VERSION) {
|
||
+ g_warning ("cache version is different: %u != %u",
|
||
+ version, IBUS_DICT_VERSION);
|
||
+ goto out_load_cache;
|
||
+ }
|
||
+
|
||
+ version = 0;
|
||
+ header = NULL;
|
||
+ g_variant_unref (variant_table);
|
||
+
|
||
+ variant_table = g_variant_new_from_data (G_VARIANT_TYPE ("(sqv)"),
|
||
+ contents,
|
||
+ length,
|
||
+ FALSE,
|
||
+ NULL,
|
||
+ NULL);
|
||
+
|
||
+ if (variant_table == NULL) {
|
||
+ g_warning ("cache table is broken.");
|
||
+ goto out_load_cache;
|
||
+ }
|
||
+
|
||
+ g_variant_get (variant_table, "(&sqv)",
|
||
+ NULL,
|
||
+ NULL,
|
||
+ &variant);
|
||
+
|
||
+ if (variant == NULL) {
|
||
+ g_warning ("cache dict is broken.");
|
||
+ goto out_load_cache;
|
||
+ }
|
||
+
|
||
+ retval = ibus_emoji_dict_deserialize (variant);
|
||
+
|
||
+out_load_cache:
|
||
+ if (variant)
|
||
+ g_variant_unref (variant);
|
||
+ if (variant_table)
|
||
+ g_variant_unref (variant_table);
|
||
+
|
||
+ return retval;
|
||
+}
|
||
+
|
||
+GSList *
|
||
+ibus_emoji_dict_lookup (GHashTable *dict,
|
||
+ const gchar *annotation)
|
||
+{
|
||
+ return (GSList *) g_hash_table_lookup (dict, annotation);
|
||
+}
|
||
diff --git a/src/ibusutil.h b/src/ibusutil.h
|
||
index 2c1360c..e619b67 100644
|
||
--- a/src/ibusutil.h
|
||
+++ b/src/ibusutil.h
|
||
@@ -2,8 +2,8 @@
|
||
/* vim:set et sts=4: */
|
||
/* bus - The Input Bus
|
||
* Copyright (C) 2008-2015 Peng Huang <shawn.p.huang@gmail.com>
|
||
- * Copyright (C) 2010-2015 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
||
- * Copyright (C) 2008-2015 Red Hat, Inc.
|
||
+ * Copyright (C) 2010-2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
||
+ * Copyright (C) 2008-2016 Red Hat, Inc.
|
||
*
|
||
* This library is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU Lesser General Public
|
||
@@ -53,4 +53,31 @@ const gchar * ibus_get_untranslated_language_name
|
||
*/
|
||
const gchar * ibus_get_language_name (const gchar *_locale);
|
||
|
||
+/**
|
||
+ * ibus_emoji_dict_save:
|
||
+ * @path: A path of the saved dictionary file.
|
||
+ * @dict: (element-type utf8 gpointer) (transfer none): An Emoji dictionary
|
||
+ *
|
||
+ * Save the Emoji dictionary to the cache file.
|
||
+ */
|
||
+void ibus_emoji_dict_save (const gchar *path,
|
||
+ GHashTable *dict);
|
||
+/**
|
||
+ * ibus_emoji_dict_load:
|
||
+ * @path: A path of the saved dictionary file.
|
||
+ *
|
||
+ * Returns: (element-type utf8 gpointer) (transfer none): An Emoji dictionary file loaded from the saved cache file.
|
||
+ */
|
||
+GHashTable * ibus_emoji_dict_load (const gchar *path);
|
||
+
|
||
+/**
|
||
+ * ibus_emoji_dict_lookup:
|
||
+ * @dict: (element-type utf8 gpointer) (transfer none): An Emoji dictionary
|
||
+ * @annotation: Annotation for Emoji characters
|
||
+ *
|
||
+ * Returns: (element-type utf8) (transfer none): List of Emoji characters
|
||
+ * This API is for gobject-introspection.
|
||
+ */
|
||
+GSList * ibus_emoji_dict_lookup (GHashTable *dict,
|
||
+ const gchar *annotation);
|
||
#endif
|
||
--
|
||
2.7.4
|
||
|
||
From 0ed644cd2b6c1d15bdba0d1c6d45d162b9b34806 Mon Sep 17 00:00:00 2001
|
||
From: fujiwarat <takao.fujiwara1@gmail.com>
|
||
Date: Thu, 23 Jun 2016 11:52:48 +0900
|
||
Subject: [PATCH 2/4] engine: Add emoji-list.html
|
||
|
||
Now we copied http://unicode.org/emoji/charts/emoji-list.html to
|
||
http://ibus.github.io/files/ibus/emoji-list.html
|
||
and download the file in the build time.
|
||
We don't save emoji-list.html in the tarball because the file size is
|
||
more than 5MB.
|
||
We always don't get the latest emoji-list.html to avoid the build error.
|
||
|
||
BUG=https://github.com/ibus/ibus/pull/1864
|
||
R=shawn.p.huang@gmail.com
|
||
|
||
Review URL: https://codereview.appspot.com/298580043
|
||
---
|
||
src/Makefile.am | 23 ++++++++++++++++++++++-
|
||
1 file changed, 22 insertions(+), 1 deletion(-)
|
||
|
||
diff --git a/src/Makefile.am b/src/Makefile.am
|
||
index a33b67d..22e031f 100644
|
||
--- a/src/Makefile.am
|
||
+++ b/src/Makefile.am
|
||
@@ -29,6 +29,15 @@ endif
|
||
|
||
SUBDIRS = . $(TESTS_DIR)
|
||
|
||
+IBUS_V_wget = $(ibus__v_wget_@AM_V@)
|
||
+ibus__v_wget_ = $(ibus__v_wget_@AM_DEFAULT_V@)
|
||
+ibus__v_wget_0 = -nv
|
||
+ibus__v_wget_1 =
|
||
+IBUS_V_diff = $(ibus__v_diff_@AM_V@)
|
||
+ibus__v_diff_ = $(ibus__v_diff_@AM_DEFAULT_V@)
|
||
+ibus__v_diff_0 = -q
|
||
+ibus__v_diff_1 =
|
||
+
|
||
# libibus = libibus-@IBUS_API_VERSION@.la
|
||
libibus = libibus-1.0.la
|
||
|
||
@@ -239,6 +248,18 @@ dict_DATA = emoji.dict
|
||
|
||
noinst_PROGRAMS = emoji-parser
|
||
|
||
+emoji-list.html:
|
||
+ $(AM_V_at)wget $(IBUS_V_wget) \
|
||
+ http://ibus.github.io/files/ibus/emoji-list.html
|
||
+ $(AM_V_at)wget $(IBUS_V_wget) \
|
||
+ http://unicode.org/emoji/charts/emoji-list.html \
|
||
+ -O latest-emoji-list.html
|
||
+ $(AM_V_at)diff $(IBUS_V_diff) emoji-list.html latest-emoji-list.html; \
|
||
+ if test $$? -ne 0; then \
|
||
+ echo "#### WARNING: emoji-list.html is old." >&2; \
|
||
+ fi; \
|
||
+ rm latest-emoji-list.html;
|
||
+
|
||
emoji.dict: emoji-parser emoji-list.html
|
||
$(builddir)/emoji-parser emoji-list.html $@
|
||
|
||
@@ -257,11 +278,11 @@ emoji_parser_LDADD = \
|
||
|
||
CLEANFILES += \
|
||
$(dict_DATA) \
|
||
+ emoji-list.html \
|
||
$(NULL)
|
||
endif
|
||
|
||
EXTRA_DIST = \
|
||
- emoji-list.html \
|
||
emoji-parser.c \
|
||
ibusversion.h.in \
|
||
ibusmarshalers.list \
|
||
--
|
||
2.7.4
|
||
|
||
From 0ee1896a2b3e75494f8f9fd9d04c27436f0877b8 Mon Sep 17 00:00:00 2001
|
||
From: fujiwarat <takao.fujiwara1@gmail.com>
|
||
Date: Thu, 7 Jul 2016 12:47:34 +0900
|
||
Subject: [PATCH 3/4] engine: Use annotations/en.xml from unocode.org but not
|
||
emoji-list.html
|
||
|
||
Downloading emoji-list would cause a different build by build site.
|
||
Now save annotations/en.xml from unicode.org and get emoji.json from
|
||
Emoji One.
|
||
en.xml is used for Unicode annotations and emoji.json is used for
|
||
aliases_ascii, e.g. ":)", and category, e.g. "people".
|
||
|
||
BUG=https://github.com/ibus/ibus/issues/1865
|
||
R=Shawn.P.Huang@gmail.com
|
||
|
||
Review URL: https://codereview.appspot.com/299530044
|
||
---
|
||
COPYING.unicode | 52 +++
|
||
Makefile.am | 1 +
|
||
configure.ac | 14 +-
|
||
data/Makefile.am | 5 +-
|
||
data/annotations/Makefile.am | 27 ++
|
||
data/annotations/en.xml | 1042 ++++++++++++++++++++++++++++++++++++++++++
|
||
ibus.spec.in | 14 +
|
||
src/Makefile.am | 31 +-
|
||
src/emoji-parser.c | 605 +++++++++++++++++++-----
|
||
9 files changed, 1634 insertions(+), 157 deletions(-)
|
||
create mode 100644 COPYING.unicode
|
||
create mode 100644 data/annotations/Makefile.am
|
||
create mode 100644 data/annotations/en.xml
|
||
|
||
diff --git a/COPYING.unicode b/COPYING.unicode
|
||
new file mode 100644
|
||
index 0000000..28d3060
|
||
--- /dev/null
|
||
+++ b/COPYING.unicode
|
||
@@ -0,0 +1,52 @@
|
||
+(Apply to data/annotations/en.xml)
|
||
+
|
||
+UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
|
||
+
|
||
+ Unicode Data Files include all data files under the directories
|
||
+http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
|
||
+http://www.unicode.org/cldr/data/. Unicode Data Files do not include PDF
|
||
+online code charts under the directory http://www.unicode.org/Public/.
|
||
+Software includes any source code published in the Unicode Standard or under
|
||
+the directories http://www.unicode.org/Public/,
|
||
+http://www.unicode.org/reports/, and http://www.unicode.org/cldr/data/.
|
||
+
|
||
+ NOTICE TO USER: Carefully read the following legal agreement. BY
|
||
+DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES
|
||
+("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND
|
||
+AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF
|
||
+YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA
|
||
+FILES OR SOFTWARE.
|
||
+
|
||
+ COPYRIGHT AND PERMISSION NOTICE
|
||
+
|
||
+ Copyright © 1991-2016 Unicode, Inc. All rights reserved. Distributed under
|
||
+the Terms of Use in http://www.unicode.org/copyright.html.
|
||
+
|
||
+ Permission is hereby granted, free of charge, to any person obtaining a
|
||
+copy of the Unicode data files and any associated documentation (the "Data
|
||
+Files") or Unicode software and any associated documentation (the "Software")
|
||
+to deal in the Data Files or Software without restriction, including without
|
||
+limitation the rights to use, copy, modify, merge, publish, distribute, and/or
|
||
+sell copies of the Data Files or Software, and to permit persons to whom the
|
||
+Data Files or Software are furnished to do so, provided that (a) the above
|
||
+copyright notice(s) and this permission notice appear with all copies of the
|
||
+Data Files or Software, (b) both the above copyright notice(s) and this
|
||
+permission notice appear in associated documentation, and (c) there is clear
|
||
+notice in each modified Data File or in the Software as well as in the
|
||
+documentation associated with the Data File(s) or Software that the data or
|
||
+software has been modified.
|
||
+
|
||
+ THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||
+KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD
|
||
+PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
|
||
+THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
|
||
+DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||
+ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE
|
||
+DATA FILES OR SOFTWARE.
|
||
+
|
||
+ Except as contained in this notice, the name of a copyright holder shall
|
||
+not be used in advertising or otherwise to promote the sale, use or other
|
||
+dealings in these Data Files or Software without prior written authorization
|
||
+of the copyright holder.
|
||
diff --git a/Makefile.am b/Makefile.am
|
||
index 3c4702c..425d1ec 100644
|
||
--- a/Makefile.am
|
||
+++ b/Makefile.am
|
||
@@ -69,6 +69,7 @@ pkgconfig_DATA = ibus-@IBUS_API_VERSION@.pc
|
||
|
||
ibus_pc_in = ibus-@IBUS_API_VERSION@.pc.in
|
||
EXTRA_DIST = \
|
||
+ COPYING.unicode \
|
||
autogen.sh \
|
||
$(ibus_pc_in) \
|
||
ibus.spec.in \
|
||
diff --git a/configure.ac b/configure.ac
|
||
index 3128ef9..f789819 100644
|
||
--- a/configure.ac
|
||
+++ b/configure.ac
|
||
@@ -608,12 +608,20 @@ AC_ARG_ENABLE(emoji-dict,
|
||
)
|
||
AM_CONDITIONAL([ENABLE_EMOJI_DICT], [test x"$enable_emoji_dict" = x"yes"])
|
||
if test x"$enable_emoji_dict" = x"yes"; then
|
||
- PKG_CHECK_MODULES(LIBXML2, [
|
||
- libxml-2.0
|
||
+ PKG_CHECK_MODULES(JSON_GLIB1, [
|
||
+ json-glib-1.0
|
||
])
|
||
enable_emoji_dict="yes (enabled, use --disable-emoji-dict to disable)"
|
||
fi
|
||
|
||
+AC_ARG_WITH(emoji-json-file,
|
||
+ AS_HELP_STRING([--with-emoji-json-file[=DIR/emoji.json]],
|
||
+ [Set emoji.json. (default: "/usr/lib/node_modules/emojione/emoji.json")]),
|
||
+ EMOJI_JSON_FILE=$with_emoji_json_file,
|
||
+ EMOJI_JSON_FILE="/usr/lib/node_modules/emojione/emoji.json"
|
||
+)
|
||
+AC_SUBST(EMOJI_JSON_FILE)
|
||
+
|
||
# Check iso-codes.
|
||
PKG_CHECK_MODULES(ISOCODES, [
|
||
iso-codes
|
||
@@ -639,6 +647,7 @@ engine/Makefile
|
||
util/Makefile
|
||
util/IMdkit/Makefile
|
||
data/Makefile
|
||
+data/annotations/Makefile.am
|
||
data/icons/Makefile
|
||
data/keymaps/Makefile
|
||
data/dconf/Makefile
|
||
@@ -698,6 +707,7 @@ Build options:
|
||
Enable surrounding-text $enable_surrounding_text
|
||
Enable libnotify $enable_libnotify
|
||
Enable Emoji dict $enable_emoji_dict
|
||
+ emoji.json path $EMOJI_JSON_FILE
|
||
Run test cases $enable_tests
|
||
])
|
||
|
||
diff --git a/data/Makefile.am b/data/Makefile.am
|
||
index e41c9a2..d9d613f 100644
|
||
--- a/data/Makefile.am
|
||
+++ b/data/Makefile.am
|
||
@@ -2,8 +2,8 @@
|
||
#
|
||
# ibus - The Input Bus
|
||
#
|
||
-# Copyright (c) 2007-2010 Peng Huang <shawn.p.huang@gmail.com>
|
||
-# Copyright (c) 2007-2010 Red Hat, Inc.
|
||
+# Copyright (c) 2007-2016 Peng Huang <shawn.p.huang@gmail.com>
|
||
+# Copyright (c) 2007-2016 Red Hat, Inc.
|
||
#
|
||
# This library is free software; you can redistribute it and/or
|
||
# modify it under the terms of the GNU Lesser General Public
|
||
@@ -21,6 +21,7 @@
|
||
# USA
|
||
|
||
SUBDIRS = \
|
||
+ annotations \
|
||
icons \
|
||
keymaps \
|
||
$(NULL)
|
||
diff --git a/data/annotations/Makefile.am b/data/annotations/Makefile.am
|
||
new file mode 100644
|
||
index 0000000..d87b933
|
||
--- /dev/null
|
||
+++ b/data/annotations/Makefile.am
|
||
@@ -0,0 +1,27 @@
|
||
+# vim:set noet ts=4:
|
||
+#
|
||
+# ibus - The Input Bus
|
||
+#
|
||
+# Copyright (c) 2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
||
+# Copyright (c) 2016 Red Hat, Inc.
|
||
+#
|
||
+# This library is free software; you can redistribute it and/or
|
||
+# modify it under the terms of the GNU Lesser General Public
|
||
+# License as published by the Free Software Foundation; either
|
||
+# version 2.1 of the License, or (at your option) any later version.
|
||
+#
|
||
+# This library is distributed in the hope that it will be useful,
|
||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+# Lesser General Public License for more details.
|
||
+#
|
||
+# You should have received a copy of the GNU Lesser General Public
|
||
+# License along with this library; if not, write to the Free Software
|
||
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||
+# USA
|
||
+
|
||
+EXTRA_DIST = \
|
||
+ en.xml \
|
||
+ $(NULL)
|
||
+
|
||
+-include $(top_srcdir)/git.mk
|
||
diff --git a/data/annotations/en.xml b/data/annotations/en.xml
|
||
new file mode 100644
|
||
index 0000000..ff7aa89
|
||
--- /dev/null
|
||
+++ b/data/annotations/en.xml
|
||
@@ -0,0 +1,1042 @@
|
||
+<?xml version='1.0' encoding='UTF-8' ?>
|
||
+<!DOCTYPE ldml SYSTEM '../../common/dtd/ldml.dtd'>
|
||
+<!-- © 1991-2015 Unicode, Inc.
|
||
+ Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
|
||
+ For terms of use, see http://www.unicode.org/copyright.html
|
||
+ CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/)
|
||
+
|
||
+ DO NOT CHANGE MANUALLY! Generated by: GenerateOtherAnnotations
|
||
+ -->
|
||
+<ldml>
|
||
+ <identity>
|
||
+ <version number="$Revision: 12320 $"/>
|
||
+ <language type='en'/>
|
||
+ </identity>
|
||
+ <annotations>
|
||
+ <annotation cp='[😀]' tts='grinning face'>face; grin</annotation>
|
||
+ <annotation cp='[😁]' tts='grinning face with smiling eyes'>eye; face; grin; smile</annotation>
|
||
+ <annotation cp='[😂]' tts='face with tears of joy'>face; joy; laugh; tear</annotation>
|
||
+ <annotation cp='[😃]' tts='smiling face with open mouth'>face; mouth; open; smile</annotation>
|
||
+ <annotation cp='[😄]' tts='smiling face with open mouth and smiling eyes'>eye; face; mouth; open; smile</annotation>
|
||
+ <annotation cp='[😅]' tts='smiling face with open mouth and cold sweat'>cold; face; open; smile; sweat</annotation>
|
||
+ <annotation cp='[😆]' tts='smiling face with open mouth and tightly-closed eyes'>face; laugh; mouth; open; satisfied; smile</annotation>
|
||
+ <annotation cp='[😉]' tts='winking face'>face; wink</annotation>
|
||
+ <annotation cp='[😊]' tts='smiling face with smiling eyes'>blush; eye; face; smile</annotation>
|
||
+ <annotation cp='[😋]' tts='face savouring delicious food'>delicious; face; savouring; smile; um; yum</annotation>
|
||
+ <annotation cp='[😎]' tts='smiling face with sunglasses'>bright; cool; eye; eyewear; face; glasses; smile; sun; sunglasses; weather</annotation>
|
||
+ <annotation cp='[😍]' tts='smiling face with heart-shaped eyes'>eye; face; heart; love; smile</annotation>
|
||
+ <annotation cp='[😘]' tts='face throwing a kiss'>face; heart; kiss</annotation>
|
||
+ <annotation cp='[😗]' tts='kissing face'>face; kiss</annotation>
|
||
+ <annotation cp='[😙]' tts='kissing face with smiling eyes'>eye; face; kiss; smile</annotation>
|
||
+ <annotation cp='[😚]' tts='kissing face with closed eyes'>closed; eye; face; kiss</annotation>
|
||
+ <annotation cp='[☺]' tts='smiling face'>face; outlined; relaxed; smile</annotation>
|
||
+ <annotation cp='[🙂]' tts='slightly smiling face'>face; smile</annotation>
|
||
+ <annotation cp='[🤗]' tts='hugging face'>face; hug; hugging</annotation>
|
||
+ <annotation cp='[😇]' tts='smiling face with halo'>angel; face; fairy tale; fantasy; halo; innocent; smile</annotation>
|
||
+ <annotation cp='[🤔]' tts='thinking face'>face; thinking</annotation>
|
||
+ <annotation cp='[😐]' tts='neutral face'>deadpan; face; neutral</annotation>
|
||
+ <annotation cp='[😑]' tts='expressionless face'>expressionless; face; inexpressive; unexpressive</annotation>
|
||
+ <annotation cp='[😶]' tts='face without mouth'>face; mouth; quiet; silent</annotation>
|
||
+ <annotation cp='[🙄]' tts='face with rolling eyes'>eyes; face; rolling</annotation>
|
||
+ <annotation cp='[😏]' tts='smirking face'>face; smirk</annotation>
|
||
+ <annotation cp='[😣]' tts='persevering face'>face; persevere</annotation>
|
||
+ <annotation cp='[😥]' tts='disappointed but relieved face'>disappointed; face; relieved; whew</annotation>
|
||
+ <annotation cp='[😮]' tts='face with open mouth'>face; mouth; open; sympathy</annotation>
|
||
+ <annotation cp='[🤐]' tts='zipper-mouth face'>face; mouth; zipper</annotation>
|
||
+ <annotation cp='[😯]' tts='hushed face'>face; hushed; stunned; surprised</annotation>
|
||
+ <annotation cp='[😪]' tts='sleepy face'>face; sleep</annotation>
|
||
+ <annotation cp='[😫]' tts='tired face'>face; tired</annotation>
|
||
+ <annotation cp='[😴]' tts='sleeping face'>face; sleep; zzz</annotation>
|
||
+ <annotation cp='[😌]' tts='relieved face'>face; relieved</annotation>
|
||
+ <annotation cp='[🤓]' tts='nerd face'>face; geek; nerd</annotation>
|
||
+ <annotation cp='[😛]' tts='face with stuck-out tongue'>face; tongue</annotation>
|
||
+ <annotation cp='[😜]' tts='face with stuck-out tongue and winking eye'>eye; face; joke; tongue; wink</annotation>
|
||
+ <annotation cp='[😝]' tts='face with stuck-out tongue and tightly-closed eyes'>eye; face; horrible; taste; tongue</annotation>
|
||
+ <annotation cp='[☹]' tts='frowning face'>face; frown</annotation>
|
||
+ <annotation cp='[🙁]' tts='slightly frowning face'>face; frown</annotation>
|
||
+ <annotation cp='[😒]' tts='unamused face'>face; unamused; unhappy</annotation>
|
||
+ <annotation cp='[😓]' tts='face with cold sweat'>cold; face; sweat</annotation>
|
||
+ <annotation cp='[😔]' tts='pensive face'>dejected; face; pensive</annotation>
|
||
+ <annotation cp='[😕]' tts='confused face'>confused; face</annotation>
|
||
+ <annotation cp='[😖]' tts='confounded face'>confounded; face</annotation>
|
||
+ <annotation cp='[🙃]' tts='upside-down face'>face; upside-down</annotation>
|
||
+ <annotation cp='[😷]' tts='face with medical mask'>cold; doctor; face; mask; medicine; sick</annotation>
|
||
+ <annotation cp='[🤒]' tts='face with thermometer'>face; ill; sick; thermometer</annotation>
|
||
+ <annotation cp='[🤕]' tts='face with head-bandage'>bandage; face; hurt; injury</annotation>
|
||
+ <annotation cp='[🤑]' tts='money-mouth face'>face; money; mouth</annotation>
|
||
+ <annotation cp='[😲]' tts='astonished face'>astonished; face; shocked; totally</annotation>
|
||
+ <annotation cp='[😞]' tts='disappointed face'>disappointed; face</annotation>
|
||
+ <annotation cp='[😟]' tts='worried face'>face; worried</annotation>
|
||
+ <annotation cp='[😤]' tts='face with steam from nose'>face; triumph; won</annotation>
|
||
+ <annotation cp='[😢]' tts='crying face'>cry; face; sad; tear</annotation>
|
||
+ <annotation cp='[😭]' tts='loudly crying face'>cry; face; sad; sob; tear</annotation>
|
||
+ <annotation cp='[😦]' tts='frowning face with open mouth'>face; frown; mouth; open</annotation>
|
||
+ <annotation cp='[😧]' tts='anguished face'>anguished; face</annotation>
|
||
+ <annotation cp='[😨]' tts='fearful face'>face; fear; fearful; scared</annotation>
|
||
+ <annotation cp='[😩]' tts='weary face'>face; tired; weary</annotation>
|
||
+ <annotation cp='[😬]' tts='grimacing face'>face; grimace</annotation>
|
||
+ <annotation cp='[😰]' tts='face with open mouth and cold sweat'>blue; cold; face; mouth; open; rushed; sweat</annotation>
|
||
+ <annotation cp='[😱]' tts='face screaming in fear'>face; fear; fearful; munch; scared; scream</annotation>
|
||
+ <annotation cp='[😳]' tts='flushed face'>dazed; face; flushed</annotation>
|
||
+ <annotation cp='[😵]' tts='dizzy face'>dizzy; face</annotation>
|
||
+ <annotation cp='[😡]' tts='pouting face'>angry; face; mad; pouting; rage; red</annotation>
|
||
+ <annotation cp='[😠]' tts='angry face'>angry; face; mad</annotation>
|
||
+ <annotation cp='[😈]' tts='smiling face with horns'>face; fairy tale; fantasy; horns; smile</annotation>
|
||
+ <annotation cp='[👿]' tts='imp'>demon; devil; face; fairy tale; fantasy</annotation>
|
||
+ <annotation cp='[👹]' tts='ogre'>creature; face; fairy tale; fantasy; japanese; monster</annotation>
|
||
+ <annotation cp='[👺]' tts='goblin'>creature; face; fairy tale; fantasy; japanese; monster</annotation>
|
||
+ <annotation cp='[💀]' tts='skull'>body; death; face; fairy tale; monster</annotation>
|
||
+ <annotation cp='[☠]' tts='skull and crossbones'>body; crossbones; death; face; monster; skull</annotation>
|
||
+ <annotation cp='[👻]' tts='ghost'>creature; face; fairy tale; fantasy; monster</annotation>
|
||
+ <annotation cp='[👽]' tts='alien'>creature; extraterrestrial; face; fairy tale; fantasy; monster; space; ufo</annotation>
|
||
+ <annotation cp='[👾]' tts='alien monster'>alien; creature; extraterrestrial; face; fairy tale; fantasy; monster; space; ufo</annotation>
|
||
+ <annotation cp='[🤖]' tts='robot face'>face; monster; robot</annotation>
|
||
+ <annotation cp='[💩]' tts='pile of poo'>comic; dung; face; monster; poo; poop</annotation>
|
||
+ <annotation cp='[😺]' tts='smiling cat face with open mouth'>cat; face; mouth; open; smile</annotation>
|
||
+ <annotation cp='[😸]' tts='grinning cat face with smiling eyes'>cat; eye; face; grin; smile</annotation>
|
||
+ <annotation cp='[😹]' tts='cat face with tears of joy'>cat; face; joy; tear</annotation>
|
||
+ <annotation cp='[😻]' tts='smiling cat face with heart-shaped eyes'>cat; eye; face; heart; love; smile</annotation>
|
||
+ <annotation cp='[😼]' tts='cat face with wry smile'>cat; face; ironic; smile; wry</annotation>
|
||
+ <annotation cp='[😽]' tts='kissing cat face with closed eyes'>cat; eye; face; kiss</annotation>
|
||
+ <annotation cp='[🙀]' tts='weary cat face'>cat; face; oh; surprised; weary</annotation>
|
||
+ <annotation cp='[😿]' tts='crying cat face'>cat; cry; face; sad; tear</annotation>
|
||
+ <annotation cp='[😾]' tts='pouting cat face'>cat; face; pouting</annotation>
|
||
+ <annotation cp='[🙈]' tts='see-no-evil'>evil; face; forbidden; gesture; monkey; no; not; prohibited; see</annotation>
|
||
+ <annotation cp='[🙉]' tts='hear-no-evil'>evil; face; forbidden; gesture; hear; monkey; no; not; prohibited</annotation>
|
||
+ <annotation cp='[🙊]' tts='speak-no-evil'>evil; face; forbidden; gesture; monkey; no; not; prohibited; speak</annotation>
|
||
+ <annotation cp='[👦]' tts='boy'>boy</annotation>
|
||
+ <annotation cp='[👧]' tts='girl'>maiden; virgin; virgo; zodiac</annotation>
|
||
+ <annotation cp='[👨]' tts='man'>man</annotation>
|
||
+ <annotation cp='[👩]' tts='woman'>woman</annotation>
|
||
+ <annotation cp='[👴]' tts='old man'>man; old</annotation>
|
||
+ <annotation cp='[👵]' tts='old woman'>old; woman</annotation>
|
||
+ <annotation cp='[👶]' tts='baby'>baby</annotation>
|
||
+ <annotation cp='[👱]' tts='person with blond hair'>blond</annotation>
|
||
+ <annotation cp='[👮]' tts='police officer'>cop; officer; police</annotation>
|
||
+ <annotation cp='[👲]' tts='man with chinese cap'>gua pi mao; hat; man</annotation>
|
||
+ <annotation cp='[👳]' tts='man with turban'>man; turban</annotation>
|
||
+ <annotation cp='[👷]' tts='construction worker'>construction; hat; worker</annotation>
|
||
+ <annotation cp='[⛑]' tts='helmet with white cross'>aid; cross; face; hat; helmet</annotation>
|
||
+ <annotation cp='[👸]' tts='princess'>fairy tale; fantasy</annotation>
|
||
+ <annotation cp='[💂]' tts='guardsman'>guard</annotation>
|
||
+ <annotation cp='[🕵]' tts='detective'>sleuth; spy</annotation>
|
||
+ <annotation cp='[🎅]' tts='santa claus'>celebration; christmas; fairy tale; fantasy; father; santa</annotation>
|
||
+ <annotation cp='[👼]' tts='baby angel'>angel; baby; face; fairy tale; fantasy</annotation>
|
||
+ <annotation cp='[💆]' tts='face massage'>massage; salon</annotation>
|
||
+ <annotation cp='[💇]' tts='haircut'>barber; beauty; parlor</annotation>
|
||
+ <annotation cp='[👰]' tts='bride with veil'>bride; veil; wedding</annotation>
|
||
+ <annotation cp='[🙍]' tts='person frowning'>frown; gesture</annotation>
|
||
+ <annotation cp='[🙎]' tts='person pouting'>gesture; pouting</annotation>
|
||
+ <annotation cp='[🙅]' tts='gesturing no'>forbidden; gesture; hand; no; not; prohibited</annotation>
|
||
+ <annotation cp='[🙆]' tts='gesturing ok'>gesture; hand; ok</annotation>
|
||
+ <annotation cp='[💁]' tts='information desk person'>hand; help; information; sassy</annotation>
|
||
+ <annotation cp='[🙋]' tts='happy person raising hand'>gesture; hand; happy; raised</annotation>
|
||
+ <annotation cp='[🙇]' tts='person bowing'>apology; bow; gesture; sorry</annotation>
|
||
+ <annotation cp='[🙌]' tts='person raising hands'>body; celebration; gesture; hand; hooray; raised</annotation>
|
||
+ <annotation cp='[🙏]' tts='folded hands'>ask; body; bow; folded; gesture; hand; please; pray; thanks</annotation>
|
||
+ <annotation cp='[🗣]' tts='speaking head'>face; head; silhouette; speak; speaking</annotation>
|
||
+ <annotation cp='[👤]' tts='bust in silhouette'>bust; silhouette</annotation>
|
||
+ <annotation cp='[👥]' tts='busts in silhouette'>bust; silhouette</annotation>
|
||
+ <annotation cp='[🚶]' tts='pedestrian'>hike; walk; walking</annotation>
|
||
+ <annotation cp='[🏃]' tts='runner'>marathon; running</annotation>
|
||
+ <annotation cp='[👯]' tts='women partying'>bunny; dancer; ear; girl; woman</annotation>
|
||
+ <annotation cp='[💃]' tts='dancer'>dancer</annotation>
|
||
+ <annotation cp='[🕴]' tts='man in business suit levitating'>business; man; suit</annotation>
|
||
+ <annotation cp='[💏]' tts='kiss'>couple; romance</annotation>
|
||
+ <annotation cp='[💑]' tts='couple with heart'>couple; heart; love; romance</annotation>
|
||
+ <annotation cp='[👪]' tts='family'>child; father; mother</annotation>
|
||
+ <annotation cp='[👫]' tts='man and woman holding hands'>couple; hand; hold; man; woman</annotation>
|
||
+ <annotation cp='[👬]' tts='two men holding hands'>couple; gemini; hand; hold; man; twins; zodiac</annotation>
|
||
+ <annotation cp='[👭]' tts='two women holding hands'>couple; hand; hold; woman</annotation>
|
||
+ <annotation cp='[🏻]' tts='skin type-1-2'>emoji modifier; fitzpatrick; skin; tone</annotation>
|
||
+ <annotation cp='[🏼]' tts='skin type-3'>emoji modifier; fitzpatrick; skin; tone</annotation>
|
||
+ <annotation cp='[🏽]' tts='skin type-4'>emoji modifier; fitzpatrick; skin; tone</annotation>
|
||
+ <annotation cp='[🏾]' tts='skin type-5'>emoji modifier; fitzpatrick; skin; tone</annotation>
|
||
+ <annotation cp='[🏿]' tts='skin type-6'>emoji modifier; fitzpatrick; skin; tone</annotation>
|
||
+ <annotation cp='[💪]' tts='flexed biceps'>biceps; body; comic; flex; muscle</annotation>
|
||
+ <annotation cp='[👈]' tts='backhand index pointing left'>backhand; body; finger; hand; index; point</annotation>
|
||
+ <annotation cp='[👉]' tts='backhand index pointing right'>backhand; body; finger; hand; index; point</annotation>
|
||
+ <annotation cp='[☝]' tts='index pointing up'>body; finger; hand; index; point; up</annotation>
|
||
+ <annotation cp='[👆]' tts='backhand index pointing up'>backhand; body; finger; hand; index; point; up</annotation>
|
||
+ <annotation cp='[🖕]' tts='middle finger'>body; finger; hand</annotation>
|
||
+ <annotation cp='[👇]' tts='backhand index pointing down'>backhand; body; down; finger; hand; index; point</annotation>
|
||
+ <annotation cp='[✌]' tts='victory hand'>body; hand; v; victory</annotation>
|
||
+ <annotation cp='[🖖]' tts='vulcan salute'>body; finger; hand; spock; vulcan</annotation>
|
||
+ <annotation cp='[🤘]' tts='sign of the horns'>body; finger; hand; horns; rock-on</annotation>
|
||
+ <annotation cp='[🖐]' tts='raised hand with fingers splayed'>body; finger; hand; splayed</annotation>
|
||
+ <annotation cp='[✋]' tts='raised hand'>body; hand</annotation>
|
||
+ <annotation cp='[👌]' tts='ok hand'>body; hand; ok</annotation>
|
||
+ <annotation cp='[👍]' tts='thumbs up'>+1; body; hand; thumb; up</annotation>
|
||
+ <annotation cp='[👎]' tts='thumbs down'>-1; body; down; hand; thumb</annotation>
|
||
+ <annotation cp='[✊]' tts='raised fist'>body; clenched; fist; hand; punch</annotation>
|
||
+ <annotation cp='[👊]' tts='oncoming fist'>body; clenched; fist; hand; punch</annotation>
|
||
+ <annotation cp='[👋]' tts='waving hand'>body; hand; wave; waving</annotation>
|
||
+ <annotation cp='[👏]' tts='clapping hands'>body; clap; hand</annotation>
|
||
+ <annotation cp='[👐]' tts='open hands'>body; hand; open</annotation>
|
||
+ <annotation cp='[✍]' tts='writing hand'>body; hand; write</annotation>
|
||
+ <annotation cp='[💅]' tts='nail polish'>body; care; cosmetics; manicure; nail; polish</annotation>
|
||
+ <annotation cp='[👂]' tts='ear'>body</annotation>
|
||
+ <annotation cp='[👃]' tts='nose'>body</annotation>
|
||
+ <annotation cp='[👣]' tts='footprints'>body; clothing; footprint; print</annotation>
|
||
+ <annotation cp='[👀]' tts='eyes'>body; eye; face</annotation>
|
||
+ <annotation cp='[👁]' tts='eye'>body</annotation>
|
||
+ <annotation cp='[👅]' tts='tongue'>body</annotation>
|
||
+ <annotation cp='[👄]' tts='mouth'>body; lips</annotation>
|
||
+ <annotation cp='[💋]' tts='kiss mark'>heart; kiss; lips; mark; romance</annotation>
|
||
+ <annotation cp='[💘]' tts='heart with arrow'>arrow; cupid; heart; romance</annotation>
|
||
+ <annotation cp='[❤]' tts='red heart'>heart</annotation>
|
||
+ <annotation cp='[💓]' tts='beating heart'>beating; heart; heartbeat; pulsating</annotation>
|
||
+ <annotation cp='[💔]' tts='broken heart'>break; broken; heart</annotation>
|
||
+ <annotation cp='[💕]' tts='two hearts'>heart; love</annotation>
|
||
+ <annotation cp='[💖]' tts='sparkling heart'>excited; heart; sparkle</annotation>
|
||
+ <annotation cp='[💗]' tts='growing heart'>excited; growing; heart; heartpulse; nervous</annotation>
|
||
+ <annotation cp='[💙]' tts='blue heart'>blue; heart</annotation>
|
||
+ <annotation cp='[💚]' tts='green heart'>green; heart</annotation>
|
||
+ <annotation cp='[💛]' tts='yellow heart'>heart; yellow</annotation>
|
||
+ <annotation cp='[💜]' tts='purple heart'>heart; purple</annotation>
|
||
+ <annotation cp='[💝]' tts='heart with ribbon'>heart; ribbon; valentine</annotation>
|
||
+ <annotation cp='[💞]' tts='revolving hearts'>heart; revolving</annotation>
|
||
+ <annotation cp='[💟]' tts='heart decoration'>heart</annotation>
|
||
+ <annotation cp='[❣]' tts='heavy heart exclamation mark ornament'>exclamation; heart; mark; punctuation</annotation>
|
||
+ <annotation cp='[💌]' tts='love letter'>heart; letter; love; mail; romance</annotation>
|
||
+ <annotation cp='[💤]' tts='zzz'>comic; sleep</annotation>
|
||
+ <annotation cp='[💢]' tts='anger symbol'>angry; comic; mad</annotation>
|
||
+ <annotation cp='[💣]' tts='bomb'>comic</annotation>
|
||
+ <annotation cp='[💥]' tts='collision'>boom; comic</annotation>
|
||
+ <annotation cp='[💦]' tts='sweat droplets'>comic; splashing; sweat</annotation>
|
||
+ <annotation cp='[💨]' tts='dashing'>comic; dash; running</annotation>
|
||
+ <annotation cp='[💫]' tts='dizzy'>comic; star</annotation>
|
||
+ <annotation cp='[💬]' tts='speech balloon'>balloon; bubble; comic; dialog; speech</annotation>
|
||
+ <annotation cp='[🗨]' tts='left speech bubble'>dialog; speech</annotation>
|
||
+ <annotation cp='[🗯]' tts='right anger bubble'>angry; balloon; bubble; mad</annotation>
|
||
+ <annotation cp='[💭]' tts='thought balloon'>balloon; bubble; comic; thought</annotation>
|
||
+ <annotation cp='[🕳]' tts='hole'>hole</annotation>
|
||
+ <annotation cp='[👓]' tts='glasses'>clothing; eye; eyeglasses; eyewear</annotation>
|
||
+ <annotation cp='[🕶]' tts='sunglasses'>dark; eye; eyewear; glasses</annotation>
|
||
+ <annotation cp='[👔]' tts='necktie'>clothing</annotation>
|
||
+ <annotation cp='[👕]' tts='t-shirt'>clothing; shirt; tshirt</annotation>
|
||
+ <annotation cp='[👖]' tts='jeans'>clothing; pants; trousers</annotation>
|
||
+ <annotation cp='[👗]' tts='dress'>clothing</annotation>
|
||
+ <annotation cp='[👘]' tts='kimono'>clothing</annotation>
|
||
+ <annotation cp='[👙]' tts='bikini'>clothing; swim</annotation>
|
||
+ <annotation cp='[👚]' tts='woman’s clothes'>clothing; woman</annotation>
|
||
+ <annotation cp='[👛]' tts='purse'>clothing; coin</annotation>
|
||
+ <annotation cp='[👜]' tts='handbag'>bag; clothing</annotation>
|
||
+ <annotation cp='[👝]' tts='pouch'>bag; clothing</annotation>
|
||
+ <annotation cp='[🛍]' tts='shopping bags'>bag; hotel; shopping</annotation>
|
||
+ <annotation cp='[🎒]' tts='school backpack'>bag; satchel; school</annotation>
|
||
+ <annotation cp='[👞]' tts='man’s shoe'>clothing; man; shoe</annotation>
|
||
+ <annotation cp='[👟]' tts='running shoe'>athletic; clothing; shoe; sneaker</annotation>
|
||
+ <annotation cp='[👠]' tts='high-heeled shoe'>clothing; heel; shoe; woman</annotation>
|
||
+ <annotation cp='[👡]' tts='woman’s sandal'>clothing; sandal; shoe; woman</annotation>
|
||
+ <annotation cp='[👢]' tts='woman’s boot'>boot; clothing; shoe; woman</annotation>
|
||
+ <annotation cp='[👑]' tts='crown'>clothing; king; queen</annotation>
|
||
+ <annotation cp='[👒]' tts='woman’s hat'>clothing; hat; woman</annotation>
|
||
+ <annotation cp='[🎩]' tts='top hat'>clothing; hat; top; tophat</annotation>
|
||
+ <annotation cp='[🎓]' tts='graduation cap'>cap; celebration; clothing; graduation; hat</annotation>
|
||
+ <annotation cp='[📿]' tts='prayer beads'>beads; clothing; necklace; prayer; religion</annotation>
|
||
+ <annotation cp='[💄]' tts='lipstick'>cosmetics; makeup</annotation>
|
||
+ <annotation cp='[💍]' tts='ring'>diamond; romance</annotation>
|
||
+ <annotation cp='[💎]' tts='gem stone'>diamond; gem; jewel; romance</annotation>
|
||
+ <annotation cp='[🐵]' tts='monkey face'>face; monkey</annotation>
|
||
+ <annotation cp='[🐒]' tts='monkey'>monkey</annotation>
|
||
+ <annotation cp='[🐶]' tts='dog face'>dog; face; pet</annotation>
|
||
+ <annotation cp='[🐕]' tts='dog'>pet</annotation>
|
||
+ <annotation cp='[🐩]' tts='poodle'>dog</annotation>
|
||
+ <annotation cp='[🐺]' tts='wolf face'>face; wolf</annotation>
|
||
+ <annotation cp='[🐱]' tts='cat face'>cat; face; pet</annotation>
|
||
+ <annotation cp='[🐈]' tts='cat'>pet</annotation>
|
||
+ <annotation cp='[🦁]' tts='lion face'>face; leo; lion; zodiac</annotation>
|
||
+ <annotation cp='[🐯]' tts='tiger face'>face; tiger</annotation>
|
||
+ <annotation cp='[🐅]' tts='tiger'>tiger</annotation>
|
||
+ <annotation cp='[🐆]' tts='leopard'>leopard</annotation>
|
||
+ <annotation cp='[🐴]' tts='horse face'>face; horse</annotation>
|
||
+ <annotation cp='[🐎]' tts='horse'>racehorse; racing</annotation>
|
||
+ <annotation cp='[🦄]' tts='unicorn face'>face; unicorn</annotation>
|
||
+ <annotation cp='[🐮]' tts='cow face'>cow; face</annotation>
|
||
+ <annotation cp='[🐂]' tts='ox'>bull; taurus; zodiac</annotation>
|
||
+ <annotation cp='[🐃]' tts='water buffalo'>buffalo; water</annotation>
|
||
+ <annotation cp='[🐄]' tts='cow'>cow</annotation>
|
||
+ <annotation cp='[🐷]' tts='pig face'>face; pig</annotation>
|
||
+ <annotation cp='[🐖]' tts='pig'>sow</annotation>
|
||
+ <annotation cp='[🐗]' tts='boar'>pig</annotation>
|
||
+ <annotation cp='[🐽]' tts='pig nose'>face; nose; pig</annotation>
|
||
+ <annotation cp='[🐏]' tts='ram'>aries; sheep; zodiac</annotation>
|
||
+ <annotation cp='[🐑]' tts='sheep'>ewe</annotation>
|
||
+ <annotation cp='[🐐]' tts='goat'>capricorn; zodiac</annotation>
|
||
+ <annotation cp='[🐪]' tts='camel'>dromedary; hump</annotation>
|
||
+ <annotation cp='[🐫]' tts='two-hump camel'>bactrian; camel; hump</annotation>
|
||
+ <annotation cp='[🐘]' tts='elephant'>elephant</annotation>
|
||
+ <annotation cp='[🐭]' tts='mouse face'>face; mouse</annotation>
|
||
+ <annotation cp='[🐁]' tts='mouse'>mouse</annotation>
|
||
+ <annotation cp='[🐀]' tts='rat'>rat</annotation>
|
||
+ <annotation cp='[🐹]' tts='hamster face'>face; hamster; pet</annotation>
|
||
+ <annotation cp='[🐰]' tts='rabbit face'>bunny; face; pet; rabbit</annotation>
|
||
+ <annotation cp='[🐇]' tts='rabbit'>bunny; pet</annotation>
|
||
+ <annotation cp='[🐿]' tts='chipmunk'>chipmunk</annotation>
|
||
+ <annotation cp='[🐻]' tts='bear face'>bear; face</annotation>
|
||
+ <annotation cp='[🐨]' tts='koala'>bear</annotation>
|
||
+ <annotation cp='[🐼]' tts='panda face'>face; panda</annotation>
|
||
+ <annotation cp='[🐾]' tts='paw prints'>feet; paw; print</annotation>
|
||
+ <annotation cp='[🦃]' tts='turkey'>turkey</annotation>
|
||
+ <annotation cp='[🐔]' tts='chicken'>chicken</annotation>
|
||
+ <annotation cp='[🐓]' tts='rooster'>rooster</annotation>
|
||
+ <annotation cp='[🐣]' tts='hatching chick'>baby; chick; hatching</annotation>
|
||
+ <annotation cp='[🐤]' tts='baby chick'>baby; chick</annotation>
|
||
+ <annotation cp='[🐥]' tts='front-facing baby chick'>baby; chick</annotation>
|
||
+ <annotation cp='[🐦]' tts='bird'>bird</annotation>
|
||
+ <annotation cp='[🐧]' tts='penguin'>penguin</annotation>
|
||
+ <annotation cp='[🕊]' tts='dove'>bird; fly; peace</annotation>
|
||
+ <annotation cp='[🐸]' tts='frog face'>face; frog</annotation>
|
||
+ <annotation cp='[🐊]' tts='crocodile'>crocodile</annotation>
|
||
+ <annotation cp='[🐢]' tts='turtle'>turtle</annotation>
|
||
+ <annotation cp='[🐍]' tts='snake'>bearer; ophiuchus; serpent; zodiac</annotation>
|
||
+ <annotation cp='[🐲]' tts='dragon face'>dragon; face; fairy tale</annotation>
|
||
+ <annotation cp='[🐉]' tts='dragon'>fairy tale</annotation>
|
||
+ <annotation cp='[🐳]' tts='spouting whale'>face; spouting; whale</annotation>
|
||
+ <annotation cp='[🐋]' tts='whale'>whale</annotation>
|
||
+ <annotation cp='[🐬]' tts='dolphin'>flipper</annotation>
|
||
+ <annotation cp='[🐟]' tts='fish'>pisces; zodiac</annotation>
|
||
+ <annotation cp='[🐠]' tts='tropical fish'>fish; tropical</annotation>
|
||
+ <annotation cp='[🐡]' tts='blowfish'>fish</annotation>
|
||
+ <annotation cp='[🐙]' tts='octopus'>octopus</annotation>
|
||
+ <annotation cp='[🐚]' tts='spiral shell'>shell; spiral</annotation>
|
||
+ <annotation cp='[🦀]' tts='crab'>cancer; zodiac</annotation>
|
||
+ <annotation cp='[🐌]' tts='snail'>snail</annotation>
|
||
+ <annotation cp='[🐛]' tts='bug'>insect</annotation>
|
||
+ <annotation cp='[🐜]' tts='ant'>insect</annotation>
|
||
+ <annotation cp='[🐝]' tts='honeybee'>bee; insect</annotation>
|
||
+ <annotation cp='[🐞]' tts='lady beetle'>beetle; insect; ladybird; ladybug</annotation>
|
||
+ <annotation cp='[🕷]' tts='spider'>insect</annotation>
|
||
+ <annotation cp='[🕸]' tts='spider web'>spider; web</annotation>
|
||
+ <annotation cp='[🦂]' tts='scorpion'>scorpio; scorpius; zodiac</annotation>
|
||
+ <annotation cp='[💐]' tts='bouquet'>flower; plant; romance</annotation>
|
||
+ <annotation cp='[🌸]' tts='cherry blossom'>blossom; cherry; flower; plant</annotation>
|
||
+ <annotation cp='[💮]' tts='white flower'>flower</annotation>
|
||
+ <annotation cp='[🏵]' tts='rosette'>plant</annotation>
|
||
+ <annotation cp='[🌹]' tts='rose'>flower; plant</annotation>
|
||
+ <annotation cp='[🌺]' tts='hibiscus'>flower; plant</annotation>
|
||
+ <annotation cp='[🌻]' tts='sunflower'>flower; plant; sun</annotation>
|
||
+ <annotation cp='[🌼]' tts='blossom'>flower; plant</annotation>
|
||
+ <annotation cp='[🌷]' tts='tulip'>flower; plant</annotation>
|
||
+ <annotation cp='[🌱]' tts='seedling'>plant; young</annotation>
|
||
+ <annotation cp='[🌲]' tts='evergreen'>plant; tree</annotation>
|
||
+ <annotation cp='[🌳]' tts='deciduous tree'>deciduous; plant; shedding; tree</annotation>
|
||
+ <annotation cp='[🌴]' tts='palm tree'>palm; plant; tree</annotation>
|
||
+ <annotation cp='[🌵]' tts='cactus'>plant</annotation>
|
||
+ <annotation cp='[🌾]' tts='sheaf of rice'>ear; plant; rice</annotation>
|
||
+ <annotation cp='[🌿]' tts='herb'>leaf; plant</annotation>
|
||
+ <annotation cp='[☘]' tts='shamrock'>plant</annotation>
|
||
+ <annotation cp='[🍀]' tts='four leaf clover'>4; clover; four; leaf; plant</annotation>
|
||
+ <annotation cp='[🍁]' tts='maple leaf'>falling; leaf; maple; plant</annotation>
|
||
+ <annotation cp='[🍂]' tts='fallen leaf'>falling; leaf; plant</annotation>
|
||
+ <annotation cp='[🍃]' tts='leaf fluttering in wind'>blow; flutter; leaf; plant; wind</annotation>
|
||
+ <annotation cp='[🍇]' tts='grapes'>fruit; grape; plant</annotation>
|
||
+ <annotation cp='[🍈]' tts='melon'>fruit; plant</annotation>
|
||
+ <annotation cp='[🍉]' tts='watermelon'>fruit; plant</annotation>
|
||
+ <annotation cp='[🍊]' tts='tangerine'>fruit; orange; plant</annotation>
|
||
+ <annotation cp='[🍋]' tts='lemon'>citrus; fruit; plant</annotation>
|
||
+ <annotation cp='[🍌]' tts='banana'>fruit; plant</annotation>
|
||
+ <annotation cp='[🍍]' tts='pineapple'>fruit; plant</annotation>
|
||
+ <annotation cp='[🍎]' tts='red apple'>apple; fruit; plant; red</annotation>
|
||
+ <annotation cp='[🍏]' tts='green apple'>apple; fruit; green; plant</annotation>
|
||
+ <annotation cp='[🍐]' tts='pear'>fruit; plant</annotation>
|
||
+ <annotation cp='[🍑]' tts='peach'>fruit; plant</annotation>
|
||
+ <annotation cp='[🍒]' tts='cherries'>cherry; fruit; plant</annotation>
|
||
+ <annotation cp='[🍓]' tts='strawberry'>berry; fruit; plant</annotation>
|
||
+ <annotation cp='[🍅]' tts='tomato'>plant; vegetable</annotation>
|
||
+ <annotation cp='[🍆]' tts='eggplant'>aubergine; plant; vegetable</annotation>
|
||
+ <annotation cp='[🌽]' tts='ear of corn'>corn; ear; maize; maze; plant</annotation>
|
||
+ <annotation cp='[🌶]' tts='hot pepper'>hot; pepper; plant</annotation>
|
||
+ <annotation cp='[🍄]' tts='mushroom'>plant</annotation>
|
||
+ <annotation cp='[🌰]' tts='chestnut'>plant</annotation>
|
||
+ <annotation cp='[🍞]' tts='bread'>loaf</annotation>
|
||
+ <annotation cp='[🧀]' tts='cheese wedge'>cheese</annotation>
|
||
+ <annotation cp='[🍖]' tts='meat on bone'>bone; meat</annotation>
|
||
+ <annotation cp='[🍗]' tts='poultry leg'>bone; chicken; leg; poultry</annotation>
|
||
+ <annotation cp='[🍔]' tts='hamburger'>burger</annotation>
|
||
+ <annotation cp='[🍟]' tts='french fries'>french; fries</annotation>
|
||
+ <annotation cp='[🍕]' tts='pizza'>cheese; slice</annotation>
|
||
+ <annotation cp='[🌭]' tts='hot dog'>frankfurter; hotdog; sausage</annotation>
|
||
+ <annotation cp='[🌮]' tts='taco'>mexican</annotation>
|
||
+ <annotation cp='[🌯]' tts='burrito'>mexican</annotation>
|
||
+ <annotation cp='[🍿]' tts='popcorn'>popcorn</annotation>
|
||
+ <annotation cp='[🍲]' tts='pot of food'>pot; stew</annotation>
|
||
+ <annotation cp='[🍱]' tts='bento box'>bento; box</annotation>
|
||
+ <annotation cp='[🍘]' tts='rice cracker'>cracker; rice</annotation>
|
||
+ <annotation cp='[🍙]' tts='rice ball'>ball; japanese; rice</annotation>
|
||
+ <annotation cp='[🍚]' tts='cooked rice'>cooked; rice</annotation>
|
||
+ <annotation cp='[🍛]' tts='curry rice'>curry; rice</annotation>
|
||
+ <annotation cp='[🍜]' tts='steaming bowl'>bowl; noodle; ramen; steaming</annotation>
|
||
+ <annotation cp='[🍝]' tts='spaghetti'>pasta</annotation>
|
||
+ <annotation cp='[🍠]' tts='roasted sweet potato'>potato; roasted; sweet</annotation>
|
||
+ <annotation cp='[🍢]' tts='oden'>kebab; seafood; skewer; stick</annotation>
|
||
+ <annotation cp='[🍣]' tts='sushi'>sushi</annotation>
|
||
+ <annotation cp='[🍤]' tts='fried shrimp'>fried; prawn; shrimp; tempura</annotation>
|
||
+ <annotation cp='[🍥]' tts='fish cake with swirl'>cake; fish; pastry; swirl</annotation>
|
||
+ <annotation cp='[🍡]' tts='dango'>dessert; japanese; skewer; stick; sweet</annotation>
|
||
+ <annotation cp='[🍦]' tts='soft ice cream'>cream; dessert; ice; icecream; soft; sweet</annotation>
|
||
+ <annotation cp='[🍧]' tts='shaved ice'>dessert; ice; shaved; sweet</annotation>
|
||
+ <annotation cp='[🍨]' tts='ice cream'>cream; dessert; ice; sweet</annotation>
|
||
+ <annotation cp='[🍩]' tts='doughnut'>dessert; donut; sweet</annotation>
|
||
+ <annotation cp='[🍪]' tts='cookie'>dessert; sweet</annotation>
|
||
+ <annotation cp='[🎂]' tts='birthday cake'>birthday; cake; celebration; dessert; pastry; sweet</annotation>
|
||
+ <annotation cp='[🍰]' tts='shortcake'>cake; dessert; pastry; slice; sweet</annotation>
|
||
+ <annotation cp='[🍫]' tts='chocolate bar'>bar; chocolate; dessert; sweet</annotation>
|
||
+ <annotation cp='[🍬]' tts='candy'>dessert; sweet</annotation>
|
||
+ <annotation cp='[🍭]' tts='lollipop'>candy; dessert; sweet</annotation>
|
||
+ <annotation cp='[🍮]' tts='custard'>dessert; pudding; sweet</annotation>
|
||
+ <annotation cp='[🍯]' tts='honey pot'>honey; honeypot; pot; sweet</annotation>
|
||
+ <annotation cp='[🍼]' tts='baby bottle'>baby; bottle; drink; milk</annotation>
|
||
+ <annotation cp='[☕]' tts='hot beverage'>beverage; coffee; drink; hot; steaming; tea</annotation>
|
||
+ <annotation cp='[🍵]' tts='teacup without handle'>beverage; cup; drink; tea; teacup</annotation>
|
||
+ <annotation cp='[🍶]' tts='sake'>bar; beverage; bottle; cup; drink</annotation>
|
||
+ <annotation cp='[🍾]' tts='bottle with popping cork'>bar; bottle; cork; drink; popping</annotation>
|
||
+ <annotation cp='[🍷]' tts='wine glass'>bar; beverage; drink; glass; wine</annotation>
|
||
+ <annotation cp='[🍸]' tts='cocktail glass'>bar; cocktail; drink; glass</annotation>
|
||
+ <annotation cp='[🍹]' tts='tropical drink'>bar; drink; tropical</annotation>
|
||
+ <annotation cp='[🍺]' tts='beer mug'>bar; beer; drink; mug</annotation>
|
||
+ <annotation cp='[🍻]' tts='clinking beer mugs'>bar; beer; clink; drink; mug</annotation>
|
||
+ <annotation cp='[🍽]' tts='fork and knife with plate'>cooking; fork; knife; plate</annotation>
|
||
+ <annotation cp='[🍴]' tts='fork and knife'>cooking; fork; knife</annotation>
|
||
+ <annotation cp='[🍳]' tts='cooking'>egg; frying; pan</annotation>
|
||
+ <annotation cp='[🏺]' tts='amphora'>aquarius; cooking; drink; jug; tool; weapon; zodiac</annotation>
|
||
+ <annotation cp='[🌍]' tts='globe showing europe-africa'>africa; earth; europe; globe; world</annotation>
|
||
+ <annotation cp='[🌎]' tts='globe showing americas'>americas; earth; globe; world</annotation>
|
||
+ <annotation cp='[🌏]' tts='globe showing asia-australia'>asia; australia; earth; globe; world</annotation>
|
||
+ <annotation cp='[🌐]' tts='globe with meridians'>earth; globe; meridians; world</annotation>
|
||
+ <annotation cp='[🗺]' tts='world map'>map; world</annotation>
|
||
+ <annotation cp='[🏔]' tts='snow-capped mountain'>cold; mountain; snow</annotation>
|
||
+ <annotation cp='[⛰]' tts='mountain'>mountain</annotation>
|
||
+ <annotation cp='[🌋]' tts='volcano'>eruption; mountain; weather</annotation>
|
||
+ <annotation cp='[🗻]' tts='mount fuji'>fuji; mountain</annotation>
|
||
+ <annotation cp='[🏕]' tts='camping'>camping</annotation>
|
||
+ <annotation cp='[🏖]' tts='beach with umbrella'>beach; umbrella</annotation>
|
||
+ <annotation cp='[🏜]' tts='desert'>desert</annotation>
|
||
+ <annotation cp='[🏝]' tts='desert island'>desert; island</annotation>
|
||
+ <annotation cp='[🏞]' tts='national park'>park</annotation>
|
||
+ <annotation cp='[🏟]' tts='stadium'>stadium</annotation>
|
||
+ <annotation cp='[🏛]' tts='classical building'>building; classical</annotation>
|
||
+ <annotation cp='[🏗]' tts='building construction'>building; construction</annotation>
|
||
+ <annotation cp='[🏘]' tts='house buildings'>building; house</annotation>
|
||
+ <annotation cp='[🏙]' tts='cityscape'>building; city</annotation>
|
||
+ <annotation cp='[🏚]' tts='derelict house building'>building; derelict; house</annotation>
|
||
+ <annotation cp='[🏠]' tts='house building'>building; home; house</annotation>
|
||
+ <annotation cp='[🏡]' tts='house with garden'>building; garden; home; house</annotation>
|
||
+ <annotation cp='[⛪]' tts='church'>building; christian; cross; religion</annotation>
|
||
+ <annotation cp='[🕋]' tts='kaaba'>islam; muslim; religion</annotation>
|
||
+ <annotation cp='[🕌]' tts='mosque'>islam; muslim; religion</annotation>
|
||
+ <annotation cp='[🕍]' tts='synagogue'>jew; jewish; religion; temple</annotation>
|
||
+ <annotation cp='[⛩]' tts='shinto shrine'>religion; shinto; shrine</annotation>
|
||
+ <annotation cp='[🏢]' tts='office building'>building</annotation>
|
||
+ <annotation cp='[🏣]' tts='japanese post office'>building; japanese; post</annotation>
|
||
+ <annotation cp='[🏤]' tts='post office'>building; european; post</annotation>
|
||
+ <annotation cp='[🏥]' tts='hospital'>building; doctor; medicine</annotation>
|
||
+ <annotation cp='[🏦]' tts='bank'>building</annotation>
|
||
+ <annotation cp='[🏨]' tts='hotel'>building</annotation>
|
||
+ <annotation cp='[🏩]' tts='love hotel'>building; hotel; love</annotation>
|
||
+ <annotation cp='[🏪]' tts='convenience store'>building; convenience; store</annotation>
|
||
+ <annotation cp='[🏫]' tts='school'>building</annotation>
|
||
+ <annotation cp='[🏬]' tts='department store'>building; department; store</annotation>
|
||
+ <annotation cp='[🏭]' tts='factory'>building</annotation>
|
||
+ <annotation cp='[🏯]' tts='japanese castle'>building; castle; japanese</annotation>
|
||
+ <annotation cp='[🏰]' tts='castle'>building; european</annotation>
|
||
+ <annotation cp='[💒]' tts='wedding'>chapel; romance</annotation>
|
||
+ <annotation cp='[🗼]' tts='tokyo tower'>tokyo; tower</annotation>
|
||
+ <annotation cp='[🗽]' tts='statue of liberty'>liberty; statue</annotation>
|
||
+ <annotation cp='[🗾]' tts='map of japan'>japan; map</annotation>
|
||
+ <annotation cp='[⛲]' tts='fountain'>fountain</annotation>
|
||
+ <annotation cp='[⛺]' tts='tent'>camping</annotation>
|
||
+ <annotation cp='[🌁]' tts='foggy'>fog; weather</annotation>
|
||
+ <annotation cp='[🌃]' tts='night with stars'>night; star; weather</annotation>
|
||
+ <annotation cp='[🌄]' tts='sunrise over mountains'>morning; mountain; sun; sunrise; weather</annotation>
|
||
+ <annotation cp='[🌅]' tts='sunrise'>morning; sun; weather</annotation>
|
||
+ <annotation cp='[🌆]' tts='cityscape at dusk'>building; city; dusk; evening; landscape; sun; sunset; weather</annotation>
|
||
+ <annotation cp='[🌇]' tts='sunset'>building; dusk; sun; weather</annotation>
|
||
+ <annotation cp='[🌉]' tts='bridge at night'>bridge; night; weather</annotation>
|
||
+ <annotation cp='[♨]' tts='hot springs'>hot; hotsprings; springs; steaming</annotation>
|
||
+ <annotation cp='[🌌]' tts='milky way'>space; weather</annotation>
|
||
+ <annotation cp='[🎠]' tts='carousel horse'>carousel; horse</annotation>
|
||
+ <annotation cp='[🎡]' tts='ferris wheel'>amusement park; ferris; wheel</annotation>
|
||
+ <annotation cp='[🎢]' tts='roller coaster'>amusement park; coaster; roller</annotation>
|
||
+ <annotation cp='[💈]' tts='barber pole'>barber; haircut; pole</annotation>
|
||
+ <annotation cp='[🎪]' tts='circus tent'>circus; tent</annotation>
|
||
+ <annotation cp='[🎭]' tts='performing arts'>art; mask; performing; theater; theatre</annotation>
|
||
+ <annotation cp='[🖼]' tts='frame with picture'>art; frame; museum; painting; picture</annotation>
|
||
+ <annotation cp='[🎨]' tts='artist palette'>art; museum; painting; palette</annotation>
|
||
+ <annotation cp='[🎰]' tts='slot machine'>game; slot</annotation>
|
||
+ <annotation cp='[🚂]' tts='locomotive'>engine; railway; steam; train; vehicle</annotation>
|
||
+ <annotation cp='[🚃]' tts='railway car'>car; electric; railway; train; tram; trolleybus; vehicle</annotation>
|
||
+ <annotation cp='[🚄]' tts='high-speed train'>railway; shinkansen; speed; train; vehicle</annotation>
|
||
+ <annotation cp='[🚅]' tts='high-speed train with bullet nose'>bullet; railway; shinkansen; speed; train; vehicle</annotation>
|
||
+ <annotation cp='[🚆]' tts='train'>railway; vehicle</annotation>
|
||
+ <annotation cp='[🚇]' tts='metro'>subway; vehicle</annotation>
|
||
+ <annotation cp='[🚈]' tts='light rail'>railway; vehicle</annotation>
|
||
+ <annotation cp='[🚉]' tts='station'>railway; train; vehicle</annotation>
|
||
+ <annotation cp='[🚊]' tts='tram'>trolleybus; vehicle</annotation>
|
||
+ <annotation cp='[🚝]' tts='monorail'>vehicle</annotation>
|
||
+ <annotation cp='[🚞]' tts='mountain railway'>car; mountain; railway; vehicle</annotation>
|
||
+ <annotation cp='[🚋]' tts='tram car'>car; tram; trolleybus; vehicle</annotation>
|
||
+ <annotation cp='[🚌]' tts='bus'>vehicle</annotation>
|
||
+ <annotation cp='[🚍]' tts='oncoming bus'>bus; oncoming; vehicle</annotation>
|
||
+ <annotation cp='[🚎]' tts='trolleybus'>bus; tram; trolley; vehicle</annotation>
|
||
+ <annotation cp='[🚏]' tts='bus stop'>bus; busstop; stop</annotation>
|
||
+ <annotation cp='[🚐]' tts='minibus'>bus; vehicle</annotation>
|
||
+ <annotation cp='[🚑]' tts='ambulance'>vehicle</annotation>
|
||
+ <annotation cp='[🚒]' tts='fire engine'>engine; fire; truck; vehicle</annotation>
|
||
+ <annotation cp='[🚓]' tts='police car'>car; patrol; police; vehicle</annotation>
|
||
+ <annotation cp='[🚔]' tts='oncoming police car'>car; oncoming; police; vehicle</annotation>
|
||
+ <annotation cp='[🚕]' tts='taxi'>vehicle</annotation>
|
||
+ <annotation cp='[🚖]' tts='oncoming taxi'>oncoming; taxi; vehicle</annotation>
|
||
+ <annotation cp='[🚗]' tts='automobile'>car; vehicle</annotation>
|
||
+ <annotation cp='[🚘]' tts='oncoming automobile'>automobile; car; oncoming; vehicle</annotation>
|
||
+ <annotation cp='[🚙]' tts='recreational vehicle'>recreational; rv; vehicle</annotation>
|
||
+ <annotation cp='[🚚]' tts='delivery truck'>delivery; truck; vehicle</annotation>
|
||
+ <annotation cp='[🚛]' tts='articulated lorry'>lorry; semi; truck; vehicle</annotation>
|
||
+ <annotation cp='[🚜]' tts='tractor'>vehicle</annotation>
|
||
+ <annotation cp='[🚲]' tts='bicycle'>bike; vehicle</annotation>
|
||
+ <annotation cp='[⛽]' tts='fuel pump'>fuel; fuelpump; gas; pump; station</annotation>
|
||
+ <annotation cp='[🛣]' tts='motorway'>highway; road</annotation>
|
||
+ <annotation cp='[🛤]' tts='railway track'>railway; train</annotation>
|
||
+ <annotation cp='[🚨]' tts='police car’s light'>beacon; car; light; police; revolving; vehicle</annotation>
|
||
+ <annotation cp='[🚥]' tts='horizontal traffic light'>light; signal; traffic</annotation>
|
||
+ <annotation cp='[🚦]' tts='vertical traffic light'>light; signal; traffic</annotation>
|
||
+ <annotation cp='[🚧]' tts='construction'>barrier</annotation>
|
||
+ <annotation cp='[⚓]' tts='anchor'>ship; tool</annotation>
|
||
+ <annotation cp='[⛵]' tts='sailboat'>boat; resort; sea; vehicle; yacht</annotation>
|
||
+ <annotation cp='[🚣]' tts='rowboat'>boat; vehicle</annotation>
|
||
+ <annotation cp='[🚤]' tts='speedboat'>boat; vehicle</annotation>
|
||
+ <annotation cp='[🛳]' tts='passenger ship'>passenger; ship; vehicle</annotation>
|
||
+ <annotation cp='[⛴]' tts='ferry'>boat</annotation>
|
||
+ <annotation cp='[🛥]' tts='motor boat'>boat; motorboat; vehicle</annotation>
|
||
+ <annotation cp='[🚢]' tts='ship'>vehicle</annotation>
|
||
+ <annotation cp='[✈]' tts='airplane'>vehicle</annotation>
|
||
+ <annotation cp='[🛩]' tts='small airplane'>airplane; vehicle</annotation>
|
||
+ <annotation cp='[🛫]' tts='airplane departure'>airplane; check-in; departure; departures; vehicle</annotation>
|
||
+ <annotation cp='[🛬]' tts='airplane arrival'>airplane; arrivals; arriving; landing; vehicle</annotation>
|
||
+ <annotation cp='[💺]' tts='seat'>chair</annotation>
|
||
+ <annotation cp='[🚁]' tts='helicopter'>vehicle</annotation>
|
||
+ <annotation cp='[🚟]' tts='suspension railway'>railway; suspension; vehicle</annotation>
|
||
+ <annotation cp='[🚠]' tts='mountain cableway'>cable; gondola; mountain; vehicle</annotation>
|
||
+ <annotation cp='[🚡]' tts='aerial tramway'>aerial; cable; car; gondola; ropeway; tramway; vehicle</annotation>
|
||
+ <annotation cp='[🚀]' tts='rocket'>space; vehicle</annotation>
|
||
+ <annotation cp='[🛰]' tts='satellite'>space; vehicle</annotation>
|
||
+ <annotation cp='[🛎]' tts='bellhop bell'>bell; bellhop; hotel</annotation>
|
||
+ <annotation cp='[🚪]' tts='door'>door</annotation>
|
||
+ <annotation cp='[🛌]' tts='person in bed'>hotel; sleep</annotation>
|
||
+ <annotation cp='[🛏]' tts='bed'>hotel; sleep</annotation>
|
||
+ <annotation cp='[🛋]' tts='couch and lamp'>couch; hotel; lamp</annotation>
|
||
+ <annotation cp='[🚽]' tts='toilet'>toilet</annotation>
|
||
+ <annotation cp='[🚿]' tts='shower'>water</annotation>
|
||
+ <annotation cp='[🛀]' tts='person taking bath'>bathtub; bath</annotation>
|
||
+ <annotation cp='[🛁]' tts='bathtub'>bath</annotation>
|
||
+ <annotation cp='[⌛]' tts='hourglass'>sand; timer</annotation>
|
||
+ <annotation cp='[⏳]' tts='hourglass with flowing sand'>hourglass; sand; timer</annotation>
|
||
+ <annotation cp='[⌚]' tts='watch'>clock</annotation>
|
||
+ <annotation cp='[⏰]' tts='alarm clock'>alarm; clock</annotation>
|
||
+ <annotation cp='[⏱]' tts='stopwatch'>clock</annotation>
|
||
+ <annotation cp='[⏲]' tts='timer clock'>clock; timer</annotation>
|
||
+ <annotation cp='[🕰]' tts='mantelpiece clock'>clock</annotation>
|
||
+ <annotation cp='[🕛]' tts='twelve o’clock'>00; 12; 12:00; clock; o’clock; twelve</annotation>
|
||
+ <annotation cp='[🕧]' tts='twelve-thirty'>12; 12:30; 30; clock; thirty; twelve</annotation>
|
||
+ <annotation cp='[🕐]' tts='one o’clock'>00; 1; 1:00; clock; o’clock; one</annotation>
|
||
+ <annotation cp='[🕜]' tts='one-thirty'>1; 1:30; 30; clock; one; thirty</annotation>
|
||
+ <annotation cp='[🕑]' tts='two o’clock'>00; 2; 2:00; clock; o’clock; two</annotation>
|
||
+ <annotation cp='[🕝]' tts='two-thirty'>2; 2:30; 30; clock; thirty; two</annotation>
|
||
+ <annotation cp='[🕒]' tts='three o’clock'>00; 3; 3:00; clock; o’clock; three</annotation>
|
||
+ <annotation cp='[🕞]' tts='three-thirty'>3; 3:30; 30; clock; thirty; three</annotation>
|
||
+ <annotation cp='[🕓]' tts='four o’clock'>00; 4; 4:00; clock; four; o’clock</annotation>
|
||
+ <annotation cp='[🕟]' tts='four-thirty'>30; 4; 4:30; clock; four; thirty</annotation>
|
||
+ <annotation cp='[🕔]' tts='five o’clock'>00; 5; 5:00; clock; five; o’clock</annotation>
|
||
+ <annotation cp='[🕠]' tts='five-thirty'>30; 5; 5:30; clock; five; thirty</annotation>
|
||
+ <annotation cp='[🕕]' tts='six o’clock'>00; 6; 6:00; clock; o’clock; six</annotation>
|
||
+ <annotation cp='[🕡]' tts='six-thirty'>30; 6; 6:30; clock; six; thirty</annotation>
|
||
+ <annotation cp='[🕖]' tts='seven o’clock'>00; 7; 7:00; clock; o’clock; seven</annotation>
|
||
+ <annotation cp='[🕢]' tts='seven-thirty'>30; 7; 7:30; clock; seven; thirty</annotation>
|
||
+ <annotation cp='[🕗]' tts='eight o’clock'>00; 8; 8:00; clock; eight; o’clock</annotation>
|
||
+ <annotation cp='[🕣]' tts='eight-thirty'>30; 8; 8:30; clock; eight; thirty</annotation>
|
||
+ <annotation cp='[🕘]' tts='nine o’clock'>00; 9; 9:00; clock; nine; o’clock</annotation>
|
||
+ <annotation cp='[🕤]' tts='nine-thirty'>30; 9; 9:30; clock; nine; thirty</annotation>
|
||
+ <annotation cp='[🕙]' tts='ten o’clock'>00; 10; 10:00; clock; o’clock; ten</annotation>
|
||
+ <annotation cp='[🕥]' tts='ten-thirty'>10; 10:30; 30; clock; ten; thirty</annotation>
|
||
+ <annotation cp='[🕚]' tts='eleven o’clock'>00; 11; 11:00; clock; eleven; o’clock</annotation>
|
||
+ <annotation cp='[🕦]' tts='eleven-thirty'>11; 11:30; 30; clock; eleven; thirty</annotation>
|
||
+ <annotation cp='[🌑]' tts='new moon'>dark; moon; space; weather</annotation>
|
||
+ <annotation cp='[🌒]' tts='waxing crescent moon'>crescent; moon; space; waxing; weather</annotation>
|
||
+ <annotation cp='[🌓]' tts='first quarter moon'>moon; quarter; space; weather</annotation>
|
||
+ <annotation cp='[🌔]' tts='waxing gibbous moon'>gibbous; moon; space; waxing; weather</annotation>
|
||
+ <annotation cp='[🌕]' tts='full moon'>full; moon; space; weather</annotation>
|
||
+ <annotation cp='[🌖]' tts='waning gibbous moon'>gibbous; moon; space; waning; weather</annotation>
|
||
+ <annotation cp='[🌗]' tts='last quarter moon'>moon; quarter; space; weather</annotation>
|
||
+ <annotation cp='[🌘]' tts='waning crescent moon'>crescent; moon; space; waning; weather</annotation>
|
||
+ <annotation cp='[🌙]' tts='crescent moon'>crescent; moon; space; weather</annotation>
|
||
+ <annotation cp='[🌚]' tts='new moon face'>face; moon; space; weather</annotation>
|
||
+ <annotation cp='[🌛]' tts='first quarter moon with face'>face; moon; quarter; space; weather</annotation>
|
||
+ <annotation cp='[🌜]' tts='last quarter moon with face'>face; moon; quarter; space; weather</annotation>
|
||
+ <annotation cp='[🌡]' tts='thermometer'>weather</annotation>
|
||
+ <annotation cp='[☀]' tts='sun'>bright; rays; space; sunny; weather</annotation>
|
||
+ <annotation cp='[🌝]' tts='full moon with face'>bright; face; full; moon; space; weather</annotation>
|
||
+ <annotation cp='[🌞]' tts='sun with face'>bright; face; space; sun; weather</annotation>
|
||
+ <annotation cp='[⭐]' tts='white medium star'>star</annotation>
|
||
+ <annotation cp='[🌟]' tts='glowing star'>glittery; glow; shining; sparkle; star</annotation>
|
||
+ <annotation cp='[🌠]' tts='shooting star'>falling; shooting; space; star</annotation>
|
||
+ <annotation cp='[☁]' tts='cloud'>weather</annotation>
|
||
+ <annotation cp='[⛅]' tts='sun behind cloud'>cloud; sun; weather</annotation>
|
||
+ <annotation cp='[⛈]' tts='cloud with lightning and rain'>cloud; rain; thunder; weather</annotation>
|
||
+ <annotation cp='[🌤]' tts='sun behind small cloud'>cloud; sun; weather</annotation>
|
||
+ <annotation cp='[🌥]' tts='sun behind large cloud'>cloud; sun; weather</annotation>
|
||
+ <annotation cp='[🌦]' tts='sun behind cloud with rain'>cloud; rain; sun; weather</annotation>
|
||
+ <annotation cp='[🌧]' tts='cloud with rain'>cloud; rain; weather</annotation>
|
||
+ <annotation cp='[🌨]' tts='cloud with snow'>cloud; cold; snow; weather</annotation>
|
||
+ <annotation cp='[🌩]' tts='cloud with lightning'>cloud; lightning; weather</annotation>
|
||
+ <annotation cp='[🌪]' tts='tornado'>cloud; weather; whirlwind</annotation>
|
||
+ <annotation cp='[🌫]' tts='fog'>cloud; weather</annotation>
|
||
+ <annotation cp='[🌬]' tts='wind face'>blow; cloud; face; weather; wind</annotation>
|
||
+ <annotation cp='[🌀]' tts='cyclone'>dizzy; twister; typhoon; weather</annotation>
|
||
+ <annotation cp='[🌈]' tts='rainbow'>rain; weather</annotation>
|
||
+ <annotation cp='[🌂]' tts='closed umbrella'>clothing; rain; umbrella; weather</annotation>
|
||
+ <annotation cp='[☂]' tts='umbrella'>clothing; rain; weather</annotation>
|
||
+ <annotation cp='[☔]' tts='umbrella with rain drops'>clothing; drop; rain; umbrella; weather</annotation>
|
||
+ <annotation cp='[⛱]' tts='umbrella on ground'>rain; sun; umbrella; weather</annotation>
|
||
+ <annotation cp='[⚡]' tts='high voltage'>danger; electric; electricity; lightning; voltage; zap</annotation>
|
||
+ <annotation cp='[❄]' tts='snowflake'>cold; snow; weather</annotation>
|
||
+ <annotation cp='[☃]' tts='snowman'>cold; snow; weather</annotation>
|
||
+ <annotation cp='[⛄]' tts='snowman without snow'>cold; snow; snowman; weather</annotation>
|
||
+ <annotation cp='[☄]' tts='comet'>space</annotation>
|
||
+ <annotation cp='[🔥]' tts='fire'>flame; tool</annotation>
|
||
+ <annotation cp='[💧]' tts='droplet'>cold; comic; drop; sweat; weather</annotation>
|
||
+ <annotation cp='[🌊]' tts='water wave'>ocean; water; wave; weather</annotation>
|
||
+ <annotation cp='[🎃]' tts='jack-o-lantern'>celebration; halloween; jack; lantern</annotation>
|
||
+ <annotation cp='[🎄]' tts='christmas tree'>celebration; christmas; tree</annotation>
|
||
+ <annotation cp='[🎆]' tts='fireworks'>celebration</annotation>
|
||
+ <annotation cp='[🎇]' tts='sparkler'>celebration; fireworks; sparkle</annotation>
|
||
+ <annotation cp='[✨]' tts='sparkles'>sparkle; star</annotation>
|
||
+ <annotation cp='[🎈]' tts='balloon'>celebration</annotation>
|
||
+ <annotation cp='[🎉]' tts='party popper'>celebration; party; popper; tada</annotation>
|
||
+ <annotation cp='[🎊]' tts='confetti ball'>ball; celebration; confetti</annotation>
|
||
+ <annotation cp='[🎋]' tts='tanabata tree'>banner; celebration; japanese; tree</annotation>
|
||
+ <annotation cp='[🎌]' tts='crossed flags'>celebration; cross; crossed; japanese</annotation>
|
||
+ <annotation cp='[🎍]' tts='pine decoration'>bamboo; celebration; japanese; pine; plant</annotation>
|
||
+ <annotation cp='[🎎]' tts='japanese dolls'>celebration; doll; festival; japanese</annotation>
|
||
+ <annotation cp='[🎏]' tts='carp streamer'>carp; celebration; streamer</annotation>
|
||
+ <annotation cp='[🎐]' tts='wind chime'>bell; celebration; chime; wind</annotation>
|
||
+ <annotation cp='[🎑]' tts='moon ceremony'>celebration; ceremony; moon</annotation>
|
||
+ <annotation cp='[🎀]' tts='ribbon'>celebration</annotation>
|
||
+ <annotation cp='[🎁]' tts='wrapped present'>box; celebration; gift; present; wrapped</annotation>
|
||
+ <annotation cp='[🎖]' tts='military medal'>celebration; medal; military</annotation>
|
||
+ <annotation cp='[🎗]' tts='reminder ribbon'>celebration; reminder; ribbon</annotation>
|
||
+ <annotation cp='[🎞]' tts='film frames'>cinema; film; frames; movie</annotation>
|
||
+ <annotation cp='[🎟]' tts='admission tickets'>admission; ticket</annotation>
|
||
+ <annotation cp='[🎫]' tts='ticket'>admission</annotation>
|
||
+ <annotation cp='[🏷]' tts='label'>label</annotation>
|
||
+ <annotation cp='[⚽]' tts='soccer ball'>ball; soccer</annotation>
|
||
+ <annotation cp='[⚾]' tts='baseball'>ball</annotation>
|
||
+ <annotation cp='[🏀]' tts='basketball'>ball; hoop</annotation>
|
||
+ <annotation cp='[🏈]' tts='american football'>american; ball; football</annotation>
|
||
+ <annotation cp='[🏉]' tts='rugby football'>ball; football; rugby</annotation>
|
||
+ <annotation cp='[🎾]' tts='tennis'>ball; racquet</annotation>
|
||
+ <annotation cp='[🎱]' tts='billiards'>8; 8 ball; ball; billiard; eight; game</annotation>
|
||
+ <annotation cp='[🎳]' tts='bowling'>ball; game</annotation>
|
||
+ <annotation cp='[⛳]' tts='flag in hole'>golf; hole</annotation>
|
||
+ <annotation cp='[🏌]' tts='golfer'>ball; golf</annotation>
|
||
+ <annotation cp='[⛸]' tts='ice skate'>ice; skate</annotation>
|
||
+ <annotation cp='[🎣]' tts='fishing pole'>fish; pole</annotation>
|
||
+ <annotation cp='[🎽]' tts='running shirt'>running; sash; shirt</annotation>
|
||
+ <annotation cp='[🎿]' tts='skis'>ski; snow</annotation>
|
||
+ <annotation cp='[⛷]' tts='skier'>ski; snow</annotation>
|
||
+ <annotation cp='[🏂]' tts='snowboarder'>ski; snow; snowboard</annotation>
|
||
+ <annotation cp='[🏄]' tts='surfer'>surfing</annotation>
|
||
+ <annotation cp='[🏇]' tts='horse racing'>horse; jockey; racehorse; racing</annotation>
|
||
+ <annotation cp='[🏊]' tts='swimmer'>swim</annotation>
|
||
+ <annotation cp='[⛹]' tts='person with ball'>ball</annotation>
|
||
+ <annotation cp='[🏋]' tts='weight lifter'>lifter; weight</annotation>
|
||
+ <annotation cp='[🚴]' tts='bicyclist'>bicycle; bike; cyclist</annotation>
|
||
+ <annotation cp='[🚵]' tts='mountain biker'>bicycle; bicyclist; bike; cyclist; mountain</annotation>
|
||
+ <annotation cp='[🏎]' tts='racing car'>car; racing</annotation>
|
||
+ <annotation cp='[🏍]' tts='motorcycle'>racing</annotation>
|
||
+ <annotation cp='[🏅]' tts='sports medal'>medal</annotation>
|
||
+ <annotation cp='[🏆]' tts='trophy'>prize</annotation>
|
||
+ <annotation cp='[🏏]' tts='cricket'>ball; bat; game</annotation>
|
||
+ <annotation cp='[🏐]' tts='volleyball'>ball; game</annotation>
|
||
+ <annotation cp='[🏑]' tts='field hockey'>ball; field; game; hockey; stick</annotation>
|
||
+ <annotation cp='[🏒]' tts='ice hockey stick and puck'>game; hockey; ice; puck; stick</annotation>
|
||
+ <annotation cp='[🏓]' tts='ping pong'>ball; bat; game; paddle; table tennis</annotation>
|
||
+ <annotation cp='[🏸]' tts='badminton'>birdie; game; racquet; shuttlecock</annotation>
|
||
+ <annotation cp='[🎯]' tts='direct hit'>bull; bullseye; dart; eye; game; hit; target</annotation>
|
||
+ <annotation cp='[🎮]' tts='video game'>controller; game</annotation>
|
||
+ <annotation cp='[🕹]' tts='joystick'>game; video game</annotation>
|
||
+ <annotation cp='[🎲]' tts='game die'>dice; die; game</annotation>
|
||
+ <annotation cp='[♠]' tts='spade suit'>card; game; spade; suit</annotation>
|
||
+ <annotation cp='[♥]' tts='heart suit'>card; game; heart; hearts; suit</annotation>
|
||
+ <annotation cp='[♦]' tts='diamond suit'>card; diamond; diamonds; game; suit</annotation>
|
||
+ <annotation cp='[♣]' tts='club suit'>card; club; clubs; game; suit</annotation>
|
||
+ <annotation cp='[🃏]' tts='joker'>card; game; playing</annotation>
|
||
+ <annotation cp='[🀄]' tts='mahjong red dragon'>game; mahjong; red</annotation>
|
||
+ <annotation cp='[🎴]' tts='flower playing cards'>card; flower; game; japanese; playing</annotation>
|
||
+ <annotation cp='[🔇]' tts='speaker off'>mute; quiet; silent; speaker; volume</annotation>
|
||
+ <annotation cp='[🔈]' tts='speaker'>volume</annotation>
|
||
+ <annotation cp='[🔉]' tts='speaker on'>low; speaker; volume; wave</annotation>
|
||
+ <annotation cp='[🔊]' tts='speaker loud'>3; high; loud; speaker; three; volume</annotation>
|
||
+ <annotation cp='[📢]' tts='loudspeaker'>loud; public address</annotation>
|
||
+ <annotation cp='[📣]' tts='megaphone'>cheering</annotation>
|
||
+ <annotation cp='[📯]' tts='postal horn'>horn; post; postal</annotation>
|
||
+ <annotation cp='[🔔]' tts='bell'>bell</annotation>
|
||
+ <annotation cp='[🔕]' tts='bell with slash'>bell; forbidden; mute; no; not; prohibited; quiet; silent</annotation>
|
||
+ <annotation cp='[🎼]' tts='musical score'>music; score</annotation>
|
||
+ <annotation cp='[🎵]' tts='musical note'>music; note</annotation>
|
||
+ <annotation cp='[🎶]' tts='musical notes'>music; note; notes</annotation>
|
||
+ <annotation cp='[🎙]' tts='studio microphone'>mic; microphone; music; studio</annotation>
|
||
+ <annotation cp='[🎚]' tts='level slider'>level; music; slider</annotation>
|
||
+ <annotation cp='[🎛]' tts='control knobs'>control; knobs; music</annotation>
|
||
+ <annotation cp='[🎤]' tts='microphone'>karaoke; mic</annotation>
|
||
+ <annotation cp='[🎧]' tts='headphone'>earbud</annotation>
|
||
+ <annotation cp='[🎷]' tts='saxophone'>instrument; music; sax</annotation>
|
||
+ <annotation cp='[🎸]' tts='guitar'>instrument; music</annotation>
|
||
+ <annotation cp='[🎹]' tts='musical keyboard'>instrument; keyboard; music; piano</annotation>
|
||
+ <annotation cp='[🎺]' tts='trumpet'>instrument; music</annotation>
|
||
+ <annotation cp='[🎻]' tts='violin'>instrument; music</annotation>
|
||
+ <annotation cp='[📻]' tts='radio'>video</annotation>
|
||
+ <annotation cp='[📱]' tts='mobile phone'>cell; mobile; phone; telephone</annotation>
|
||
+ <annotation cp='[📲]' tts='mobile phone with arrow'>arrow; call; cell; mobile; phone; receive; telephone</annotation>
|
||
+ <annotation cp='[☎]' tts='telephone'>phone</annotation>
|
||
+ <annotation cp='[📞]' tts='telephone receiver'>phone; receiver; telephone</annotation>
|
||
+ <annotation cp='[📟]' tts='pager'>pager</annotation>
|
||
+ <annotation cp='[📠]' tts='fax machine'>fax</annotation>
|
||
+ <annotation cp='[🔋]' tts='battery'>battery</annotation>
|
||
+ <annotation cp='[🔌]' tts='electric plug'>electric; electricity; plug</annotation>
|
||
+ <annotation cp='[💻]' tts='laptop computer'>computer; pc; personal</annotation>
|
||
+ <annotation cp='[🖥]' tts='desktop computer'>computer; desktop</annotation>
|
||
+ <annotation cp='[🖨]' tts='printer'>computer</annotation>
|
||
+ <annotation cp='[⌨]' tts='keyboard'>computer</annotation>
|
||
+ <annotation cp='[🖱]' tts='computer mouse'>3; button; computer; mouse; three</annotation>
|
||
+ <annotation cp='[🖲]' tts='trackball'>computer</annotation>
|
||
+ <annotation cp='[💽]' tts='minidisc'>computer; disk; minidisk; optical</annotation>
|
||
+ <annotation cp='[💾]' tts='floppy disk'>computer; disk; floppy</annotation>
|
||
+ <annotation cp='[💿]' tts='optical disc'>dvd; blu-ray; cd; computer; disk; optical</annotation>
|
||
+ <annotation cp='[📀]' tts='dvd'>blu-ray; cd; computer; disk; optical</annotation>
|
||
+ <annotation cp='[🎥]' tts='movie camera'>camera; cinema; movie</annotation>
|
||
+ <annotation cp='[🎬]' tts='clapper board'>clapper; movie</annotation>
|
||
+ <annotation cp='[📽]' tts='film projector'>cinema; film; movie; projector; video</annotation>
|
||
+ <annotation cp='[📺]' tts='television'>tv; video</annotation>
|
||
+ <annotation cp='[📷]' tts='camera'>video</annotation>
|
||
+ <annotation cp='[📸]' tts='camera with flash'>camera; flash; video</annotation>
|
||
+ <annotation cp='[📹]' tts='video camera'>camera; video</annotation>
|
||
+ <annotation cp='[📼]' tts='videocassette'>tape; vhs; video</annotation>
|
||
+ <annotation cp='[🔍]' tts='left-pointing magnifying glass'>glass; magnifying; search; tool</annotation>
|
||
+ <annotation cp='[🔎]' tts='right-pointing magnifying glass'>glass; magnifying; search; tool</annotation>
|
||
+ <annotation cp='[🔬]' tts='microscope'>tool</annotation>
|
||
+ <annotation cp='[🔭]' tts='telescope'>tool</annotation>
|
||
+ <annotation cp='[📡]' tts='satellite antenna'>antenna; dish; satellite</annotation>
|
||
+ <annotation cp='[🕯]' tts='candle'>light</annotation>
|
||
+ <annotation cp='[💡]' tts='light bulb'>bulb; comic; electric; idea; light</annotation>
|
||
+ <annotation cp='[🔦]' tts='flashlight'>electric; light; tool; torch</annotation>
|
||
+ <annotation cp='[🏮]' tts='red paper lantern'>bar; japanese; lantern; light; red</annotation>
|
||
+ <annotation cp='[📔]' tts='notebook with decorative cover'>book; cover; decorated; notebook</annotation>
|
||
+ <annotation cp='[📕]' tts='closed book'>book; closed</annotation>
|
||
+ <annotation cp='[📖]' tts='open book'>book; open</annotation>
|
||
+ <annotation cp='[📗]' tts='green book'>book; green</annotation>
|
||
+ <annotation cp='[📘]' tts='blue book'>blue; book</annotation>
|
||
+ <annotation cp='[📙]' tts='orange book'>book; orange</annotation>
|
||
+ <annotation cp='[📚]' tts='books'>book</annotation>
|
||
+ <annotation cp='[📓]' tts='notebook'>notebook</annotation>
|
||
+ <annotation cp='[📒]' tts='ledger'>notebook</annotation>
|
||
+ <annotation cp='[📃]' tts='page with curl'>curl; document; page</annotation>
|
||
+ <annotation cp='[📜]' tts='scroll'>paper</annotation>
|
||
+ <annotation cp='[📄]' tts='page facing up'>document; page</annotation>
|
||
+ <annotation cp='[📰]' tts='newspaper'>news; paper</annotation>
|
||
+ <annotation cp='[🗞]' tts='rolled-up newspaper'>news; newspaper; paper; rolled</annotation>
|
||
+ <annotation cp='[📑]' tts='bookmark tabs'>bookmark; mark; marker; tabs</annotation>
|
||
+ <annotation cp='[🔖]' tts='bookmark'>mark</annotation>
|
||
+ <annotation cp='[💰]' tts='money bag'>bag; dollar; money; moneybag</annotation>
|
||
+ <annotation cp='[💴]' tts='yen banknote'>bank; banknote; bill; currency; money; note; yen</annotation>
|
||
+ <annotation cp='[💵]' tts='dollar banknote'>bank; banknote; bill; currency; dollar; money; note</annotation>
|
||
+ <annotation cp='[💶]' tts='euro banknote'>bank; banknote; bill; currency; euro; money; note</annotation>
|
||
+ <annotation cp='[💷]' tts='pound banknote'>bank; banknote; bill; currency; money; note; pound</annotation>
|
||
+ <annotation cp='[💸]' tts='money with wings'>bank; banknote; bill; dollar; fly; money; note; wings</annotation>
|
||
+ <annotation cp='[💳]' tts='credit card'>bank; card; credit; money</annotation>
|
||
+ <annotation cp='[💹]' tts='chart increasing with yen'>bank; chart; currency; graph; growth; market; money; rise; trend; upward; yen</annotation>
|
||
+ <annotation cp='[✉]' tts='envelope'>e-mail; email</annotation>
|
||
+ <annotation cp='[📧]' tts='e-mail'>email; letter; mail</annotation>
|
||
+ <annotation cp='[📨]' tts='incoming envelope'>e-mail; email; envelope; incoming; letter; mail; receive</annotation>
|
||
+ <annotation cp='[📩]' tts='envelope with arrow'>arrow; down; e-mail; email; envelope; letter; mail; outgoing; sent</annotation>
|
||
+ <annotation cp='[📤]' tts='outbox tray'>box; letter; mail; outbox; sent; tray</annotation>
|
||
+ <annotation cp='[📥]' tts='inbox tray'>box; inbox; letter; mail; receive; tray</annotation>
|
||
+ <annotation cp='[📦]' tts='package'>box; parcel</annotation>
|
||
+ <annotation cp='[📫]' tts='closed mailbox with raised flag'>closed; mail; mailbox; postbox</annotation>
|
||
+ <annotation cp='[📪]' tts='closed mailbox with lowered flag'>closed; lowered; mail; mailbox; postbox</annotation>
|
||
+ <annotation cp='[📬]' tts='open mailbox with raised flag'>mail; mailbox; open; postbox</annotation>
|
||
+ <annotation cp='[📭]' tts='open mailbox with lowered flag'>lowered; mail; mailbox; open; postbox</annotation>
|
||
+ <annotation cp='[📮]' tts='postbox'>mail; mailbox</annotation>
|
||
+ <annotation cp='[🗳]' tts='ballot box with ballot'>ballot; box</annotation>
|
||
+ <annotation cp='[✏]' tts='pencil'>pencil</annotation>
|
||
+ <annotation cp='[✒]' tts='black nib'>nib; pen</annotation>
|
||
+ <annotation cp='[🖋]' tts='fountain pen'>fountain; pen</annotation>
|
||
+ <annotation cp='[🖊]' tts='pen'>ballpoint</annotation>
|
||
+ <annotation cp='[🖌]' tts='paintbrush'>painting</annotation>
|
||
+ <annotation cp='[🖍]' tts='crayon'>crayon</annotation>
|
||
+ <annotation cp='[📝]' tts='memo'>pencil</annotation>
|
||
+ <annotation cp='[💼]' tts='briefcase'>briefcase</annotation>
|
||
+ <annotation cp='[📁]' tts='file folder'>file; folder</annotation>
|
||
+ <annotation cp='[📂]' tts='open file folder'>file; folder; open</annotation>
|
||
+ <annotation cp='[🗂]' tts='card index dividers'>card; dividers; index</annotation>
|
||
+ <annotation cp='[📅]' tts='calendar'>date</annotation>
|
||
+ <annotation cp='[📆]' tts='tear-off calendar'>calendar</annotation>
|
||
+ <annotation cp='[🗒]' tts='spiral notepad'>note; pad; spiral</annotation>
|
||
+ <annotation cp='[🗓]' tts='spiral calendar'>calendar; pad; spiral</annotation>
|
||
+ <annotation cp='[📇]' tts='card index'>card; index; rolodex</annotation>
|
||
+ <annotation cp='[📈]' tts='chart increasing'>chart; graph; growth; trend; upward</annotation>
|
||
+ <annotation cp='[📉]' tts='chart decreasing'>chart; down; graph; trend</annotation>
|
||
+ <annotation cp='[📊]' tts='bar chart'>bar; chart; graph</annotation>
|
||
+ <annotation cp='[📋]' tts='clipboard'>clipboard</annotation>
|
||
+ <annotation cp='[📌]' tts='pushpin'>pin</annotation>
|
||
+ <annotation cp='[📍]' tts='round pushpin'>pin; pushpin</annotation>
|
||
+ <annotation cp='[📎]' tts='paperclip'>paperclip</annotation>
|
||
+ <annotation cp='[🖇]' tts='linked paperclips'>link; paperclip</annotation>
|
||
+ <annotation cp='[📏]' tts='straight ruler'>ruler; straight edge</annotation>
|
||
+ <annotation cp='[📐]' tts='triangular ruler'>ruler; set; triangle</annotation>
|
||
+ <annotation cp='[✂]' tts='scissors'>tool</annotation>
|
||
+ <annotation cp='[🗃]' tts='card file box'>box; card; file</annotation>
|
||
+ <annotation cp='[🗄]' tts='file cabinet'>cabinet; file</annotation>
|
||
+ <annotation cp='[🗑]' tts='wastebasket'>wastebasket</annotation>
|
||
+ <annotation cp='[🔒]' tts='lock'>closed</annotation>
|
||
+ <annotation cp='[🔓]' tts='open lock'>lock; open; unlock</annotation>
|
||
+ <annotation cp='[🔏]' tts='lock with pen'>ink; lock; nib; pen; privacy</annotation>
|
||
+ <annotation cp='[🔐]' tts='closed lock with key'>closed; key; lock; secure</annotation>
|
||
+ <annotation cp='[🔑]' tts='key'>lock; password</annotation>
|
||
+ <annotation cp='[🗝]' tts='old key'>clue; key; lock; old</annotation>
|
||
+ <annotation cp='[🔨]' tts='hammer'>tool</annotation>
|
||
+ <annotation cp='[⛏]' tts='pick'>mining; tool</annotation>
|
||
+ <annotation cp='[⚒]' tts='hammer and pick'>hammer; pick; tool</annotation>
|
||
+ <annotation cp='[🛠]' tts='hammer and wrench'>hammer; tool; wrench</annotation>
|
||
+ <annotation cp='[🔧]' tts='wrench'>tool</annotation>
|
||
+ <annotation cp='[🔩]' tts='nut and bolt'>bolt; nut; tool</annotation>
|
||
+ <annotation cp='[⚙]' tts='gear'>tool</annotation>
|
||
+ <annotation cp='[🗜]' tts='compression'>tool; vice</annotation>
|
||
+ <annotation cp='[⚗]' tts='alembic'>chemistry; tool</annotation>
|
||
+ <annotation cp='[⚖]' tts='balance scale'>balance; justice; libra; scales; tool; weight; zodiac</annotation>
|
||
+ <annotation cp='[🔗]' tts='link'>link</annotation>
|
||
+ <annotation cp='[⛓]' tts='chains'>chain</annotation>
|
||
+ <annotation cp='[💉]' tts='syringe'>doctor; medicine; needle; shot; sick; tool</annotation>
|
||
+ <annotation cp='[💊]' tts='pill'>doctor; medicine; sick</annotation>
|
||
+ <annotation cp='[🗡]' tts='dagger'>knife; weapon</annotation>
|
||
+ <annotation cp='[🔪]' tts='kitchen knife'>cooking; hocho; knife; tool; weapon</annotation>
|
||
+ <annotation cp='[⚔]' tts='crossed swords'>crossed; swords; weapon</annotation>
|
||
+ <annotation cp='[🔫]' tts='pistol'>gun; handgun; revolver; tool; weapon</annotation>
|
||
+ <annotation cp='[🛡]' tts='shield'>weapon</annotation>
|
||
+ <annotation cp='[🏹]' tts='bow and arrow'>archer; arrow; bow; sagittarius; tool; weapon; zodiac</annotation>
|
||
+ <annotation cp='[🏁]' tts='chequered flag'>checkered; chequered; racing</annotation>
|
||
+ <annotation cp='[🏳]' tts='waving white flag'>waving</annotation>
|
||
+ <annotation cp='[🏴]' tts='waving black flag'>waving</annotation>
|
||
+ <annotation cp='[🚩]' tts='triangular flag'>post</annotation>
|
||
+ <annotation cp='[🚬]' tts='smoking'>smoking</annotation>
|
||
+ <annotation cp='[⚰]' tts='coffin'>death</annotation>
|
||
+ <annotation cp='[⚱]' tts='funeral urn'>death; funeral; urn</annotation>
|
||
+ <annotation cp='[🗿]' tts='moai'>face; moyai; statue</annotation>
|
||
+ <annotation cp='[🛢]' tts='oil drum'>drum; oil</annotation>
|
||
+ <annotation cp='[🔮]' tts='crystal ball'>ball; crystal; fairy tale; fantasy; fortune; tool</annotation>
|
||
+ <annotation cp='[🏧]' tts='ATM sign'>atm; automated; bank; teller</annotation>
|
||
+ <annotation cp='[🚮]' tts='litter in bin sign'>litter; litterbox</annotation>
|
||
+ <annotation cp='[🚰]' tts='potable water'>drink; potable; water</annotation>
|
||
+ <annotation cp='[♿]' tts='wheelchair'>access</annotation>
|
||
+ <annotation cp='[🚹]' tts='men’s room'>lavatory; man; restroom; wc</annotation>
|
||
+ <annotation cp='[🚺]' tts='women’s room'>lavatory; restroom; wc; woman</annotation>
|
||
+ <annotation cp='[🚻]' tts='restroom'>lavatory; wc</annotation>
|
||
+ <annotation cp='[🚼]' tts='baby symbol'>baby; changing</annotation>
|
||
+ <annotation cp='[🚾]' tts='water closet'>closet; lavatory; restroom; water; wc</annotation>
|
||
+ <annotation cp='[🛂]' tts='passport control'>control; passport</annotation>
|
||
+ <annotation cp='[🛃]' tts='customs'>customs</annotation>
|
||
+ <annotation cp='[🛄]' tts='baggage claim'>baggage; claim</annotation>
|
||
+ <annotation cp='[🛅]' tts='left luggage'>baggage; locker; luggage</annotation>
|
||
+ <annotation cp='[⚠]' tts='warning'>warning</annotation>
|
||
+ <annotation cp='[🚸]' tts='children crossing'>child; crossing; pedestrian; traffic</annotation>
|
||
+ <annotation cp='[⛔]' tts='no entry'>entry; forbidden; no; not; prohibited; traffic</annotation>
|
||
+ <annotation cp='[🚫]' tts='prohibited'>entry; forbidden; no; not</annotation>
|
||
+ <annotation cp='[🚳]' tts='no bicycles'>bicycle; bike; forbidden; no; not; prohibited; vehicle</annotation>
|
||
+ <annotation cp='[🚭]' tts='no smoking'>forbidden; no; not; prohibited; smoking</annotation>
|
||
+ <annotation cp='[🚯]' tts='no littering'>forbidden; litter; no; not; prohibited</annotation>
|
||
+ <annotation cp='[🚱]' tts='non-potable water'>drink; forbidden; no; not; potable; prohibited; water</annotation>
|
||
+ <annotation cp='[🚷]' tts='no pedestrians'>forbidden; no; not; pedestrian; prohibited</annotation>
|
||
+ <annotation cp='[☢]' tts='radioactive'>radioactive</annotation>
|
||
+ <annotation cp='[☣]' tts='biohazard'>biohazard</annotation>
|
||
+ <annotation cp='[⬆]' tts='up arrow'>arrow; cardinal; direction; north</annotation>
|
||
+ <annotation cp='[↗]' tts='up-right arrow'>arrow; direction; intercardinal; northeast</annotation>
|
||
+ <annotation cp='[➡]' tts='right arrow'>arrow; cardinal; direction; east</annotation>
|
||
+ <annotation cp='[↘]' tts='down-right arrow'>arrow; direction; intercardinal; southeast</annotation>
|
||
+ <annotation cp='[⬇]' tts='down arrow'>arrow; cardinal; direction; down; south</annotation>
|
||
+ <annotation cp='[↙]' tts='down-left arrow'>arrow; direction; intercardinal; southwest</annotation>
|
||
+ <annotation cp='[⬅]' tts='left arrow'>arrow; cardinal; direction; west</annotation>
|
||
+ <annotation cp='[↖]' tts='up-left arrow'>arrow; direction; intercardinal; northwest</annotation>
|
||
+ <annotation cp='[↕]' tts='up-down arrow'>arrow</annotation>
|
||
+ <annotation cp='[↔]' tts='left-right arrow'>arrow</annotation>
|
||
+ <annotation cp='[↩]' tts='right arrow curving left'>arrow</annotation>
|
||
+ <annotation cp='[↪]' tts='left arrow curving right'>arrow</annotation>
|
||
+ <annotation cp='[⤴]' tts='right arrow curving up'>arrow</annotation>
|
||
+ <annotation cp='[⤵]' tts='right arrow curving down'>arrow; down</annotation>
|
||
+ <annotation cp='[🔃]' tts='clockwise vertical arrows'>arrow; clockwise; reload</annotation>
|
||
+ <annotation cp='[🔄]' tts='anticlockwise arrows button'>anticlockwise; arrow; counterclockwise; withershins</annotation>
|
||
+ <annotation cp='[🔙]' tts='back arrow'>arrow; back</annotation>
|
||
+ <annotation cp='[🔚]' tts='end arrow'>arrow; end</annotation>
|
||
+ <annotation cp='[🔛]' tts='on! arrow'>arrow; mark; on</annotation>
|
||
+ <annotation cp='[🔜]' tts='soon arrow'>arrow; soon</annotation>
|
||
+ <annotation cp='[🔝]' tts='top arrow'>arrow; top; up</annotation>
|
||
+ <annotation cp='[🛐]' tts='place of worship'>religion; worship</annotation>
|
||
+ <annotation cp='[⚛]' tts='atom symbol'>atheist; atom</annotation>
|
||
+ <annotation cp='[🕉]' tts='om'>hindu; religion</annotation>
|
||
+ <annotation cp='[✡]' tts='star of david'>david; jew; jewish; religion; star</annotation>
|
||
+ <annotation cp='[☸]' tts='wheel of dharma'>buddhist; dharma; religion; wheel</annotation>
|
||
+ <annotation cp='[☯]' tts='yin yang'>religion; tao; taoist; yang; yin</annotation>
|
||
+ <annotation cp='[✝]' tts='latin cross'>christian; cross; religion</annotation>
|
||
+ <annotation cp='[☦]' tts='orthodox cross'>christian; cross; religion</annotation>
|
||
+ <annotation cp='[☪]' tts='star and crescent'>islam; muslim; religion</annotation>
|
||
+ <annotation cp='[☮]' tts='peace symbol'>peace</annotation>
|
||
+ <annotation cp='[🕎]' tts='menorah'>candelabrum; candlestick; religion</annotation>
|
||
+ <annotation cp='[🔯]' tts='dotted six-pointed star'>fortune; star</annotation>
|
||
+ <annotation cp='[♻]' tts='recycling symbol'>recycle</annotation>
|
||
+ <annotation cp='[📛]' tts='name badge'>badge; name</annotation>
|
||
+ <annotation cp='[⚜]' tts='fleur-de-lis'>fleur-de-lis</annotation>
|
||
+ <annotation cp='[🔰]' tts='japanese symbol for beginner'>beginner; chevron; green; japanese; leaf; tool; yellow</annotation>
|
||
+ <annotation cp='[🔱]' tts='trident emblem'>anchor; emblem; ship; tool; trident</annotation>
|
||
+ <annotation cp='[⭕]' tts='heavy large circle'>circle; o</annotation>
|
||
+ <annotation cp='[✅]' tts='white heavy check mark'>check; mark</annotation>
|
||
+ <annotation cp='[☑]' tts='ballot box with check'>ballot; box; check</annotation>
|
||
+ <annotation cp='[✔]' tts='heavy check mark'>check; mark</annotation>
|
||
+ <annotation cp='[✖]' tts='heavy multiplication x'>cancel; multiplication; multiply; x</annotation>
|
||
+ <annotation cp='[❌]' tts='cross mark'>cancel; mark; multiplication; multiply; x</annotation>
|
||
+ <annotation cp='[❎]' tts='cross mark button'>mark; square</annotation>
|
||
+ <annotation cp='[➕]' tts='heavy plus sign'>math; plus</annotation>
|
||
+ <annotation cp='[➖]' tts='heavy minus sign'>math; minus</annotation>
|
||
+ <annotation cp='[➗]' tts='heavy division sign'>division; math</annotation>
|
||
+ <annotation cp='[➰]' tts='curly loop'>curl; loop</annotation>
|
||
+ <annotation cp='[➿]' tts='double curly loop'>curl; double; loop</annotation>
|
||
+ <annotation cp='[〽]' tts='part alternation mark'>mark; part</annotation>
|
||
+ <annotation cp='[✳]' tts='eight-spoked asterisk'>asterisk</annotation>
|
||
+ <annotation cp='[✴]' tts='eight-pointed star'>star</annotation>
|
||
+ <annotation cp='[❇]' tts='sparkle'>sparkle</annotation>
|
||
+ <annotation cp='[💱]' tts='currency exchange'>bank; currency; exchange; money</annotation>
|
||
+ <annotation cp='[💲]' tts='heavy dollar sign'>currency; dollar; money</annotation>
|
||
+ <annotation cp='[‼]' tts='double exclamation mark'>bangbang; exclamation; mark; punctuation</annotation>
|
||
+ <annotation cp='[⁉]' tts='exclamation question mark'>exclamation; interrobang; mark; punctuation; question</annotation>
|
||
+ <annotation cp='[❓]' tts='question mark'>mark; punctuation; question</annotation>
|
||
+ <annotation cp='[❔]' tts='white question mark'>mark; outlined; punctuation; question</annotation>
|
||
+ <annotation cp='[❕]' tts='white exclamation mark'>exclamation; mark; outlined; punctuation</annotation>
|
||
+ <annotation cp='[❗]' tts='exclamation mark'>exclamation; mark; punctuation</annotation>
|
||
+ <annotation cp='[〰]' tts='wavy dash'>dash; punctuation; wavy</annotation>
|
||
+ <annotation cp='[©]' tts='copyright'>copyright</annotation>
|
||
+ <annotation cp='[®]' tts='registered'>registered</annotation>
|
||
+ <annotation cp='[™]' tts='trade mark'>mark; tm; trademark</annotation>
|
||
+ <annotation cp='[♈]' tts='aries'>ram; zodiac</annotation>
|
||
+ <annotation cp='[♉]' tts='taurus'>bull; ox; zodiac</annotation>
|
||
+ <annotation cp='[♊]' tts='gemini'>twins; zodiac</annotation>
|
||
+ <annotation cp='[♋]' tts='cancer'>crab; zodiac</annotation>
|
||
+ <annotation cp='[♌]' tts='leo'>lion; zodiac</annotation>
|
||
+ <annotation cp='[♍]' tts='virgo'>maiden; virgin; zodiac</annotation>
|
||
+ <annotation cp='[♎]' tts='libra'>balance; justice; scales; zodiac</annotation>
|
||
+ <annotation cp='[♏]' tts='scorpius'>scorpio; scorpion; zodiac</annotation>
|
||
+ <annotation cp='[♐]' tts='sagittarius'>archer; zodiac</annotation>
|
||
+ <annotation cp='[♑]' tts='capricorn'>goat; zodiac</annotation>
|
||
+ <annotation cp='[♒]' tts='aquarius'>bearer; water; zodiac</annotation>
|
||
+ <annotation cp='[♓]' tts='pisces'>fish; zodiac</annotation>
|
||
+ <annotation cp='[⛎]' tts='ophiuchus'>bearer; serpent; snake; zodiac</annotation>
|
||
+ <annotation cp='[🔀]' tts='shuffle tracks button'>arrow; crossed</annotation>
|
||
+ <annotation cp='[🔁]' tts='repeat button'>arrow; clockwise; repeat</annotation>
|
||
+ <annotation cp='[🔂]' tts='repeat single button'>arrow; clockwise; once</annotation>
|
||
+ <annotation cp='[▶]' tts='play button'>arrow; play; right; triangle</annotation>
|
||
+ <annotation cp='[⏩]' tts='fast-forword button'>arrow; double; fast; forward</annotation>
|
||
+ <annotation cp='[⏭]' tts='next track button'>arrow; next scene; next track; triangle</annotation>
|
||
+ <annotation cp='[⏯]' tts='play or pause button'>arrow; pause; play; right; triangle</annotation>
|
||
+ <annotation cp='[◀]' tts='reverse button'>arrow; left; reverse; triangle</annotation>
|
||
+ <annotation cp='[⏪]' tts='fast reverse button'>arrow; double; rewind</annotation>
|
||
+ <annotation cp='[⏮]' tts='last track button'>arrow; previous scene; previous track; triangle</annotation>
|
||
+ <annotation cp='[🔼]' tts='up button'>arrow; button; red</annotation>
|
||
+ <annotation cp='[⏫]' tts='fast up button'>arrow; double</annotation>
|
||
+ <annotation cp='[🔽]' tts='down button'>arrow; button; down; red</annotation>
|
||
+ <annotation cp='[⏬]' tts='fast down button'>arrow; double; down</annotation>
|
||
+ <annotation cp='[⏸]' tts='pause button'>bar; double; pause; vertical</annotation>
|
||
+ <annotation cp='[⏹]' tts='stop button'>square; stop</annotation>
|
||
+ <annotation cp='[⏺]' tts='record button'>circle; record</annotation>
|
||
+ <annotation cp='[⏏]' tts='eject button'>eject</annotation>
|
||
+ <annotation cp='[🎦]' tts='cinema'>camera; film; movie</annotation>
|
||
+ <annotation cp='[🔅]' tts='dim button'>brightness; dim; low</annotation>
|
||
+ <annotation cp='[🔆]' tts='bright button'>bright; brightness</annotation>
|
||
+ <annotation cp='[📶]' tts='antenna bars'>antenna; bar; cell; mobile; phone; signal; telephone</annotation>
|
||
+ <annotation cp='[📵]' tts='no mobile phones'>cell; forbidden; mobile; no; not; phone; prohibited; telephone</annotation>
|
||
+ <annotation cp='[📳]' tts='vibration mode'>cell; mobile; mode; phone; telephone; vibration</annotation>
|
||
+ <annotation cp='[📴]' tts='mobile phone off'>cell; mobile; off; phone; telephone</annotation>
|
||
+ <annotation cp='[{#⃣}]' tts='keycap number'>hash; keycap; pound</annotation>
|
||
+ <annotation cp='[{*⃣}]' tts='keycap asterisk'>asterisk; keycap; star</annotation>
|
||
+ <annotation cp='[{0⃣}]' tts='keycap digit zero'>0; keycap; zero</annotation>
|
||
+ <annotation cp='[{1⃣}]' tts='keycap digit one'>1; keycap; one</annotation>
|
||
+ <annotation cp='[{2⃣}]' tts='keycap digit two'>2; keycap; two</annotation>
|
||
+ <annotation cp='[{3⃣}]' tts='keycap digit three'>3; keycap; three</annotation>
|
||
+ <annotation cp='[{4⃣}]' tts='keycap digit four'>4; four; keycap</annotation>
|
||
+ <annotation cp='[{5⃣}]' tts='keycap digit five'>5; five; keycap</annotation>
|
||
+ <annotation cp='[{6⃣}]' tts='keycap digit six'>6; keycap; six</annotation>
|
||
+ <annotation cp='[{7⃣}]' tts='keycap digit seven'>7; keycap; seven</annotation>
|
||
+ <annotation cp='[{8⃣}]' tts='keycap digit eight'>8; eight; keycap</annotation>
|
||
+ <annotation cp='[{9⃣}]' tts='keycap digit nine'>9; keycap; nine</annotation>
|
||
+ <annotation cp='[🔟]' tts='keycap ten'>10; keycap; ten</annotation>
|
||
+ <annotation cp='[💯]' tts='hundred points'>100; full; hundred; score</annotation>
|
||
+ <annotation cp='[🔞]' tts='no one under eighteen'>18; age restriction; eighteen; forbidden; no; not; prohibited; underage</annotation>
|
||
+ <annotation cp='[🔠]' tts='input latin uppercase'>input; latin; letters; uppercase</annotation>
|
||
+ <annotation cp='[🔡]' tts='input latin lowercase'>abcd; input; latin; letters; lowercase</annotation>
|
||
+ <annotation cp='[🔢]' tts='input numbers'>1234; input; numbers</annotation>
|
||
+ <annotation cp='[🔣]' tts='input symbols'>input</annotation>
|
||
+ <annotation cp='[🔤]' tts='input latin letters'>abc; alphabet; input; latin; letters</annotation>
|
||
+ <annotation cp='[🅰]' tts='a button'>a; blood</annotation>
|
||
+ <annotation cp='[🆎]' tts='ab button'>ab; blood</annotation>
|
||
+ <annotation cp='[🅱]' tts='b button'>b; blood</annotation>
|
||
+ <annotation cp='[🆑]' tts='squared cl'>cl</annotation>
|
||
+ <annotation cp='[🆒]' tts='squared cool'>cool</annotation>
|
||
+ <annotation cp='[🆓]' tts='squared free'>free</annotation>
|
||
+ <annotation cp='[ℹ]' tts='information source'>i; information</annotation>
|
||
+ <annotation cp='[🆔]' tts='squared id'>id; identity</annotation>
|
||
+ <annotation cp='[Ⓜ]' tts='circled letter m'>circle; m</annotation>
|
||
+ <annotation cp='[🆕]' tts='squared new'>new</annotation>
|
||
+ <annotation cp='[🆖]' tts='squared ng'>ng</annotation>
|
||
+ <annotation cp='[🅾]' tts='o button'>blood; o</annotation>
|
||
+ <annotation cp='[🆗]' tts='squared ok'>ok</annotation>
|
||
+ <annotation cp='[🅿]' tts='p button'>parking</annotation>
|
||
+ <annotation cp='[🆘]' tts='squared sos'>help; sos</annotation>
|
||
+ <annotation cp='[🆙]' tts='up! button'>mark; up</annotation>
|
||
+ <annotation cp='[🆚]' tts='squared vs'>versus; vs</annotation>
|
||
+ <annotation cp='[🈁]' tts='squared katakana koko'>japanese</annotation>
|
||
+ <annotation cp='[🈂]' tts='squared katakana sa'>japanese</annotation>
|
||
+ <annotation cp='[🈷]' tts='squared moon ideograph'>japanese</annotation>
|
||
+ <annotation cp='[🈶]' tts='squared exist ideograph'>japanese</annotation>
|
||
+ <annotation cp='[🈯]' tts='squared finger ideograph'>japanese</annotation>
|
||
+ <annotation cp='[🉐]' tts='circled advantage ideograph'>japanese</annotation>
|
||
+ <annotation cp='[🈹]' tts='squared divide ideograph'>japanese</annotation>
|
||
+ <annotation cp='[🈚]' tts='squared negation ideograph'>japanese</annotation>
|
||
+ <annotation cp='[🈲]' tts='squared prohibit ideograph'>japanese</annotation>
|
||
+ <annotation cp='[🉑]' tts='circled accept ideograph'>chinese</annotation>
|
||
+ <annotation cp='[🈸]' tts='squared apply ideograph'>chinese</annotation>
|
||
+ <annotation cp='[🈴]' tts='squared together ideograph'>chinese</annotation>
|
||
+ <annotation cp='[🈳]' tts='squared empty ideograph'>chinese</annotation>
|
||
+ <annotation cp='[㊗]' tts='circled congratulate ideograph'>chinese; congratulation; congratulations; ideograph</annotation>
|
||
+ <annotation cp='[㊙]' tts='circled secret ideograph'>chinese; ideograph; secret</annotation>
|
||
+ <annotation cp='[🈺]' tts='squared operating ideograph'>chinese</annotation>
|
||
+ <annotation cp='[🈵]' tts='squared fullness ideograph'>chinese</annotation>
|
||
+ <annotation cp='[▪]' tts='black small square'>geometric; square</annotation>
|
||
+ <annotation cp='[▫]' tts='white small square'>geometric; square</annotation>
|
||
+ <annotation cp='[◻]' tts='white medium square'>geometric; square</annotation>
|
||
+ <annotation cp='[◼]' tts='black medium square'>geometric; square</annotation>
|
||
+ <annotation cp='[◽]' tts='white medium-small square'>geometric; square</annotation>
|
||
+ <annotation cp='[◾]' tts='black medium-small square'>geometric; square</annotation>
|
||
+ <annotation cp='[⬛]' tts='black large square'>geometric; square</annotation>
|
||
+ <annotation cp='[⬜]' tts='white large square'>geometric; square</annotation>
|
||
+ <annotation cp='[🔶]' tts='large orange diamond'>diamond; geometric; orange</annotation>
|
||
+ <annotation cp='[🔷]' tts='large blue diamond'>blue; diamond; geometric</annotation>
|
||
+ <annotation cp='[🔸]' tts='small orange diamond'>diamond; geometric; orange</annotation>
|
||
+ <annotation cp='[🔹]' tts='small blue diamond'>blue; diamond; geometric</annotation>
|
||
+ <annotation cp='[🔺]' tts='red triangle pointed up'>geometric; red</annotation>
|
||
+ <annotation cp='[🔻]' tts='red triangle pointed down'>down; geometric; red</annotation>
|
||
+ <annotation cp='[💠]' tts='diamond with a dot'>comic; diamond; geometric; inside</annotation>
|
||
+ <annotation cp='[🔘]' tts='radio button'>button; geometric; radio</annotation>
|
||
+ <annotation cp='[🔲]' tts='black square button'>button; geometric; square</annotation>
|
||
+ <annotation cp='[🔳]' tts='white square button'>button; geometric; outlined; square</annotation>
|
||
+ <annotation cp='[⚪]' tts='white circle'>circle; geometric</annotation>
|
||
+ <annotation cp='[⚫]' tts='black circle'>circle; geometric</annotation>
|
||
+ <annotation cp='[🔴]' tts='red circle'>circle; geometric; red</annotation>
|
||
+ <annotation cp='[🔵]' tts='blue circle'>blue; circle; geometric</annotation>
|
||
+ </annotations>
|
||
+</ldml>
|
||
\ No newline at end of file
|
||
diff --git a/ibus.spec.in b/ibus.spec.in
|
||
index 7fdaccb..40aead1 100644
|
||
--- a/ibus.spec.in
|
||
+++ b/ibus.spec.in
|
||
@@ -5,6 +5,7 @@
|
||
|
||
# Build flags
|
||
%define build_python_library 0
|
||
+%define build_emoji_dictionary 1
|
||
|
||
%define glib_ver %([ -a %{_libdir}/pkgconfig/glib-2.0.pc ] && pkg-config --modversion glib-2.0 | cut -d. -f 1,2 || echo -n "999")
|
||
%define gconf2_version 2.12.0
|
||
@@ -40,6 +41,10 @@ BuildRequires: dconf-devel
|
||
BuildRequires: pygobject2-devel
|
||
BuildRequires: intltool
|
||
BuildRequires: iso-codes-devel
|
||
+%if %build_emoji_dictionary
|
||
+BuildRequires: nodejs-emojione
|
||
+BuildRequires: json-glib
|
||
+%endif
|
||
|
||
Requires: %{name}-libs = %{version}-%{release}
|
||
Requires: %{name}-gtk2 = %{version}-%{release}
|
||
@@ -151,6 +156,12 @@ OPTIONS="$OPTIONS --enable-python-library"
|
||
%else
|
||
OPTIONS="$OPTIONS --disable-python-library"
|
||
%endif
|
||
+%if %build_emoji_dictionary
|
||
+OPTIONS="$OPTIONS --enable-emoji-dict"
|
||
+%else
|
||
+OPTIONS="$OPTIONS --disable-emoji-dict"
|
||
+%endif
|
||
+
|
||
|
||
%configure $OPTIONS
|
||
|
||
@@ -258,6 +269,9 @@ dconf update &> /dev/null || :
|
||
%{_bindir}/ibus-setup
|
||
%{_datadir}/ibus/component/gtkpanel.xml
|
||
%{_datadir}/ibus/component/simple.xml
|
||
+%if %build_emoji_dictionary
|
||
+%{_datadir}/ibus/dicts
|
||
+%endif
|
||
%{_datadir}/ibus/keymaps/*
|
||
%{_datadir}/ibus/setup/*
|
||
|
||
diff --git a/src/Makefile.am b/src/Makefile.am
|
||
index 22e031f..b58ab95 100644
|
||
--- a/src/Makefile.am
|
||
+++ b/src/Makefile.am
|
||
@@ -29,15 +29,6 @@ endif
|
||
|
||
SUBDIRS = . $(TESTS_DIR)
|
||
|
||
-IBUS_V_wget = $(ibus__v_wget_@AM_V@)
|
||
-ibus__v_wget_ = $(ibus__v_wget_@AM_DEFAULT_V@)
|
||
-ibus__v_wget_0 = -nv
|
||
-ibus__v_wget_1 =
|
||
-IBUS_V_diff = $(ibus__v_diff_@AM_V@)
|
||
-ibus__v_diff_ = $(ibus__v_diff_@AM_DEFAULT_V@)
|
||
-ibus__v_diff_0 = -q
|
||
-ibus__v_diff_1 =
|
||
-
|
||
# libibus = libibus-@IBUS_API_VERSION@.la
|
||
libibus = libibus-1.0.la
|
||
|
||
@@ -248,37 +239,25 @@ dict_DATA = emoji.dict
|
||
|
||
noinst_PROGRAMS = emoji-parser
|
||
|
||
-emoji-list.html:
|
||
- $(AM_V_at)wget $(IBUS_V_wget) \
|
||
- http://ibus.github.io/files/ibus/emoji-list.html
|
||
- $(AM_V_at)wget $(IBUS_V_wget) \
|
||
- http://unicode.org/emoji/charts/emoji-list.html \
|
||
- -O latest-emoji-list.html
|
||
- $(AM_V_at)diff $(IBUS_V_diff) emoji-list.html latest-emoji-list.html; \
|
||
- if test $$? -ne 0; then \
|
||
- echo "#### WARNING: emoji-list.html is old." >&2; \
|
||
- fi; \
|
||
- rm latest-emoji-list.html;
|
||
-
|
||
-emoji.dict: emoji-parser emoji-list.html
|
||
- $(builddir)/emoji-parser emoji-list.html $@
|
||
+emoji.dict: emoji-parser
|
||
+ $(builddir)/emoji-parser --xml $(srcdir)/../data/annotations/en.xml \
|
||
+ --json $(EMOJI_JSON_FILE) --out $@
|
||
|
||
emoji_parser_SOURCES = \
|
||
emoji-parser.c \
|
||
$(NULL)
|
||
emoji_parser_CFLAGS = \
|
||
$(GLIB2_CFLAGS) \
|
||
- $(LIBXML2_CFLAGS) \
|
||
+ $(JSON_GLIB1_CFLAGS) \
|
||
$(NULL)
|
||
emoji_parser_LDADD = \
|
||
$(GLIB2_LIBS) \
|
||
- $(LIBXML2_LIBS) \
|
||
+ $(JSON_GLIB1_LIBS) \
|
||
$(libibus) \
|
||
$(NULL)
|
||
|
||
CLEANFILES += \
|
||
$(dict_DATA) \
|
||
- emoji-list.html \
|
||
$(NULL)
|
||
endif
|
||
|
||
diff --git a/src/emoji-parser.c b/src/emoji-parser.c
|
||
index cf92fee..e97f266 100644
|
||
--- a/src/emoji-parser.c
|
||
+++ b/src/emoji-parser.c
|
||
@@ -20,47 +20,59 @@
|
||
* USA
|
||
*/
|
||
|
||
-/* Convert http://www.unicode.org/emoji/charts/emoji-list.html
|
||
+/* Convert ../data/annotations/en.xml and
|
||
+ * /usr/lib/node_modules/emojione/emoji.json
|
||
* to the dictionary file which look up the Emoji from the annotation.
|
||
+ * Get emoji.json with 'npm install -g emojione'.
|
||
+ * en.xml is used for the Unicode annotations and emoji.json is used
|
||
+ * for the aliases_ascii, e.g. ":)", and category, e.g. "people".
|
||
*/
|
||
|
||
#include <glib.h>
|
||
-#include <libxml/HTMLparser.h>
|
||
-#include <libgen.h>
|
||
+#include <json-glib/json-glib.h>
|
||
+
|
||
+#include <string.h>
|
||
|
||
#include "ibusutil.h"
|
||
|
||
typedef struct _EmojiData EmojiData;
|
||
struct _EmojiData {
|
||
- gchar *class;
|
||
gchar *emoji;
|
||
- GSList *annotates;
|
||
- GSList *prev_annotates;
|
||
+ GSList *annotations;
|
||
+ gboolean is_annotation;
|
||
GHashTable *dict;
|
||
};
|
||
|
||
-const gchar *progname;
|
||
-
|
||
-static gboolean parse_node (xmlNode *node,
|
||
- gboolean is_child,
|
||
- const gchar *prop_name,
|
||
- EmojiData *data);
|
||
-
|
||
static void
|
||
-usage (void)
|
||
+reset_emoji_element (EmojiData *data)
|
||
{
|
||
- g_print ("%s emoji-list.html emoji.dict\n", progname);
|
||
+ g_assert (data != NULL);
|
||
+
|
||
+ g_clear_pointer (&data->emoji, g_free);
|
||
+ g_slist_free_full (data->annotations, g_free);
|
||
+ data->annotations = NULL;
|
||
}
|
||
|
||
static void
|
||
-reset_emoji_element (EmojiData *data)
|
||
+update_emoji_dict (EmojiData *data)
|
||
{
|
||
- g_clear_pointer (&data->class, g_free);
|
||
- g_clear_pointer (&data->emoji, g_free);
|
||
- if (data->annotates) {
|
||
- g_slist_free_full (data->prev_annotates, g_free);
|
||
- data->prev_annotates = data->annotates;
|
||
- data->annotates = NULL;
|
||
+ GSList *annotations = data->annotations;
|
||
+ while (annotations) {
|
||
+ const gchar *annotation = (const gchar *) annotations->data;
|
||
+ GSList *emojis = g_hash_table_lookup (data->dict, annotation);
|
||
+ if (emojis) {
|
||
+ GSList *duplicated = g_slist_find_custom (emojis,
|
||
+ data->emoji,
|
||
+ (GCompareFunc) g_strcmp0);
|
||
+ if (duplicated != NULL)
|
||
+ continue;
|
||
+ emojis = g_slist_copy_deep (emojis, (GCopyFunc) g_strdup, NULL);
|
||
+ }
|
||
+ emojis = g_slist_append (emojis, g_strdup (data->emoji));
|
||
+ g_hash_table_replace (data->dict,
|
||
+ g_strdup (annotation),
|
||
+ emojis);
|
||
+ annotations = annotations->next;
|
||
}
|
||
}
|
||
|
||
@@ -70,147 +82,486 @@ free_dict_words (gpointer list)
|
||
g_slist_free_full (list, g_free);
|
||
}
|
||
|
||
-static gboolean
|
||
-parse_attr (xmlAttr *attr,
|
||
- EmojiData *data)
|
||
-{
|
||
- if (g_strcmp0 ((const gchar *) attr->name, "class") == 0 && attr->children)
|
||
- parse_node (attr->children, TRUE, (const gchar *) attr->name, data);
|
||
- if (g_strcmp0 ((const gchar *) attr->name, "target") == 0 && attr->children)
|
||
- parse_node (attr->children, TRUE, (const gchar *) attr->name, data);
|
||
- if (attr->next)
|
||
- parse_attr (attr->next, data);
|
||
- return TRUE;
|
||
-}
|
||
+static void
|
||
+unicode_annotations_start_element_cb (GMarkupParseContext *context,
|
||
+ const gchar *element_name,
|
||
+ const gchar **attribute_names,
|
||
+ const gchar **attribute_values,
|
||
+ gpointer user_data,
|
||
+ GError **error)
|
||
+{
|
||
+ EmojiData *data = (EmojiData *) user_data;
|
||
+ int i;
|
||
+ const gchar *attribute;
|
||
+ const gchar *value;
|
||
|
||
-static gboolean
|
||
-parse_node (xmlNode *node,
|
||
- gboolean is_child,
|
||
- const gchar *prop_name,
|
||
- EmojiData *data)
|
||
-{
|
||
- if (g_strcmp0 ((const gchar *) node->name, "tr") == 0) {
|
||
- GSList *annotates = data->annotates;
|
||
- while (annotates) {
|
||
- GSList *emojis = g_hash_table_lookup (data->dict, annotates->data);
|
||
- if (emojis) {
|
||
- emojis = g_slist_copy_deep (emojis, (GCopyFunc) g_strdup, NULL);
|
||
+ g_assert (data != NULL);
|
||
+
|
||
+ if (g_strcmp0 (element_name, "annotation") != 0)
|
||
+ return;
|
||
+
|
||
+ reset_emoji_element (data);
|
||
+
|
||
+ for (i = 0; (attribute = attribute_names[i]) != NULL; i++) {
|
||
+ value = attribute_values[i];
|
||
+
|
||
+ if (g_strcmp0 (attribute, "cp") == 0) {
|
||
+ if (value == NULL || *value == '\0') {
|
||
+ g_warning ("cp='' in unicode.org annotations file");
|
||
+ return;
|
||
+ } else if (value[0] != '[' || value[strlen(value) - 1] != ']') {
|
||
+ g_warning ("cp!='[emoji]' in unicode.org annotations file");
|
||
+ return;
|
||
}
|
||
- emojis = g_slist_append (emojis, g_strdup (data->emoji));
|
||
- g_hash_table_replace (data->dict,
|
||
- g_strdup (annotates->data),
|
||
- emojis);
|
||
- annotates = annotates->next;
|
||
+ data->emoji = g_strndup (value + 1, strlen(value) - 2);
|
||
}
|
||
- reset_emoji_element (data);
|
||
- }
|
||
- /* if node->name is "text" and is_child is FALSE,
|
||
- * it's '\n' or Space between <td> and <td>.
|
||
- */
|
||
- if (g_strcmp0 ((const gchar *) node->name, "text") == 0 && is_child) {
|
||
- /* Get "chars" in <td class="chars"> */
|
||
- if (g_strcmp0 (prop_name, "class") == 0) {
|
||
- if (g_strcmp0 (data->class, (const gchar *) node->content) != 0) {
|
||
- g_clear_pointer (&data->class, g_free);
|
||
- data->class = g_strdup ((const gchar *) node->content);
|
||
+ else if (g_strcmp0 (attribute, "tts") == 0) {
|
||
+ GSList *duplicated = g_slist_find_custom (data->annotations,
|
||
+ value,
|
||
+ (GCompareFunc) g_strcmp0);
|
||
+ if (duplicated == NULL) {
|
||
+ data->annotations = g_slist_prepend (data->annotations,
|
||
+ g_strdup (value));
|
||
}
|
||
}
|
||
- /* Get "annotate" in <td class="name"><a target="annotate"> */
|
||
- if (g_strcmp0 (prop_name, "target") == 0 &&
|
||
- g_strcmp0 (data->class, "name") == 0) {
|
||
- g_clear_pointer (&data->class, g_free);
|
||
- data->class = g_strdup ((const gchar *) node->content);
|
||
- }
|
||
- /* Get "emoji" in <td class="chars">emoji</td> */
|
||
- if (g_strcmp0 (prop_name, "td") == 0 &&
|
||
- g_strcmp0 (data->class, "chars") == 0) {
|
||
- data->emoji = g_strdup ((const gchar *) node->content);
|
||
- }
|
||
- /* We ignore "NAME" for <td class="name">NAME</td> but
|
||
- * takes "ANNOTATE" for
|
||
- * <td class="name"><a target="annotate">ANNOTATE</a></td>
|
||
- */
|
||
- if (g_strcmp0 (prop_name, "td") == 0 &&
|
||
- g_strcmp0 (data->class, "name") == 0) {
|
||
- g_slist_free_full (data->annotates, g_free);
|
||
- data->annotates = NULL;
|
||
+ }
|
||
+
|
||
+ data->is_annotation = TRUE;
|
||
+}
|
||
+
|
||
+static void
|
||
+unicode_annotations_end_element_cb (GMarkupParseContext *context,
|
||
+ const gchar *element_name,
|
||
+ gpointer user_data,
|
||
+ GError **error)
|
||
+{
|
||
+ EmojiData *data = (EmojiData *) user_data;
|
||
+
|
||
+ g_assert (data != NULL);
|
||
+ if (!data->is_annotation)
|
||
+ return;
|
||
+
|
||
+ update_emoji_dict (data);
|
||
+ data->is_annotation = FALSE;
|
||
+}
|
||
+
|
||
+void
|
||
+unicode_annotations_text_cb (GMarkupParseContext *context,
|
||
+ const gchar *text,
|
||
+ gsize text_len,
|
||
+ gpointer user_data,
|
||
+ GError **error)
|
||
+{
|
||
+ EmojiData *data = (EmojiData *) user_data;
|
||
+ gchar **annotations = NULL;
|
||
+ const gchar *annotation;
|
||
+ int i;
|
||
+
|
||
+ g_assert (data != NULL);
|
||
+ if (!data->is_annotation)
|
||
+ return;
|
||
+ annotations = g_strsplit (text, "; ", -1);
|
||
+ for (i = 0; (annotation = annotations[i]) != NULL; i++) {
|
||
+ GSList *duplicated = g_slist_find_custom (data->annotations,
|
||
+ annotation,
|
||
+ (GCompareFunc) g_strcmp0);
|
||
+ if (duplicated == NULL) {
|
||
+ data->annotations = g_slist_prepend (data->annotations,
|
||
+ g_strdup (annotation));
|
||
}
|
||
- /* Get "ANNOTATE" in
|
||
- * <td class="name"><a target="annotate">ANNOTATE</a></td>
|
||
- */
|
||
- if (g_strcmp0 (prop_name, "a") == 0 &&
|
||
- g_strcmp0 (data->class, "annotate") == 0) {
|
||
- data->annotates =
|
||
- g_slist_append (data->annotates,
|
||
- g_strdup ((const gchar *) node->content));
|
||
+ }
|
||
+ g_strfreev (annotations);
|
||
+}
|
||
+
|
||
+static gboolean
|
||
+unicode_annotations_parse_xml_file (const gchar *filename,
|
||
+ GHashTable *dict)
|
||
+{
|
||
+ gchar *content = NULL;
|
||
+ gsize length = 0;
|
||
+ GError *error = NULL;
|
||
+ const static GMarkupParser parser = {
|
||
+ unicode_annotations_start_element_cb,
|
||
+ unicode_annotations_end_element_cb,
|
||
+ unicode_annotations_text_cb,
|
||
+ NULL,
|
||
+ NULL
|
||
+ };
|
||
+ GMarkupParseContext *context = NULL;
|
||
+ EmojiData data = { 0, };
|
||
+
|
||
+ g_return_val_if_fail (filename != NULL, FALSE);
|
||
+ g_return_val_if_fail (dict != NULL, FALSE);
|
||
+
|
||
+ if (!g_file_get_contents (filename, &content, &length, &error)) {
|
||
+ g_warning ("Failed to load %s: %s", filename, error->message);
|
||
+ goto failed_to_parse_unicode_annotations;
|
||
+ }
|
||
+
|
||
+ data.dict = dict;
|
||
+
|
||
+ context = g_markup_parse_context_new (&parser, 0, &data, NULL);
|
||
+ if (!g_markup_parse_context_parse (context, content, length, &error)) {
|
||
+ g_warning ("Failed to parse %s: %s", filename, error->message);
|
||
+ goto failed_to_parse_unicode_annotations;
|
||
+ }
|
||
+
|
||
+ reset_emoji_element (&data);
|
||
+ g_markup_parse_context_free (context);
|
||
+ g_free (content);
|
||
+ return TRUE;
|
||
+
|
||
+failed_to_parse_unicode_annotations:
|
||
+ if (error)
|
||
+ g_error_free (error);
|
||
+ if (data.dict)
|
||
+ g_hash_table_destroy (data.dict);
|
||
+ if (context)
|
||
+ g_markup_parse_context_free (context);
|
||
+ g_free (content);
|
||
+ return FALSE;
|
||
+}
|
||
+
|
||
+static gboolean
|
||
+parse_emojione_unicode (JsonNode *node,
|
||
+ EmojiData *data)
|
||
+{
|
||
+ const gchar *str, *unicode;
|
||
+ gchar *endptr = NULL;
|
||
+ guint32 uch;
|
||
+ static gchar outbuf[8] = { 0, };
|
||
+ GString *emoji;
|
||
+
|
||
+ if (json_node_get_node_type (node) != JSON_NODE_VALUE) {
|
||
+ g_warning ("'unicode' element is not string");
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
+ emoji = g_string_new (NULL);
|
||
+ str = unicode = json_node_get_string (node);
|
||
+ while (str && *str) {
|
||
+ uch = g_ascii_strtoull (str, &endptr, 16);
|
||
+ outbuf[g_unichar_to_utf8 (uch, outbuf)] = '\0';
|
||
+ g_string_append (emoji, outbuf);
|
||
+ if (*endptr == '\0') {
|
||
+ break;
|
||
+ } else {
|
||
+ switch (*endptr) {
|
||
+ case '-':
|
||
+ endptr++;
|
||
+ break;
|
||
+ default:
|
||
+ g_warning ("Failed to parse unicode %s", unicode);
|
||
+ }
|
||
}
|
||
+ str = endptr;
|
||
+ endptr = NULL;
|
||
+ }
|
||
+
|
||
+ data->emoji = g_string_free (emoji, FALSE);
|
||
+
|
||
+ return TRUE;
|
||
+}
|
||
+
|
||
+static gboolean
|
||
+parse_emojione_shortname (JsonNode *node,
|
||
+ EmojiData *data)
|
||
+{
|
||
+#if 0
|
||
+ const gchar *shortname;
|
||
+ gchar *head, *s;
|
||
+ int length;
|
||
+ GSList *duplicated;
|
||
+
|
||
+ if (json_node_get_node_type (node) != JSON_NODE_VALUE) {
|
||
+ g_warning ("'shortname' element is not string");
|
||
+ return FALSE;
|
||
}
|
||
- /* Get "foo" in <td class="foo"> */
|
||
- if (g_strcmp0 ((const gchar *) node->name, "td") == 0 &&
|
||
- node->properties != NULL) {
|
||
- parse_attr (node->properties, data);
|
||
+
|
||
+ /* The format is ':short_name:' */
|
||
+ shortname = json_node_get_string (node);
|
||
+ if (shortname == 0 || *shortname == '\0')
|
||
+ return TRUE;
|
||
+ if (*shortname != ':') {
|
||
+ g_warning ("'shortname' format is different: %s", shortname);
|
||
+ return FALSE;
|
||
}
|
||
- /* Get "foo" in <a target="foo"> */
|
||
- if (g_strcmp0 ((const gchar *) node->name, "a") == 0 &&
|
||
- node->properties != NULL) {
|
||
- parse_attr (node->properties, data);
|
||
+
|
||
+ length = strlen (shortname);
|
||
+ head = g_new0 (gchar, length);
|
||
+ strcpy (head, shortname + 1);
|
||
+ for (s = head; *s; s++) {
|
||
+ if (*s == ':') {
|
||
+ *s = '\0';
|
||
+ break;
|
||
+ } else if (*s == '_') {
|
||
+ *s = ' ';
|
||
+ }
|
||
}
|
||
- if (node->children) {
|
||
- parse_node (node->children, TRUE, (const gchar *) node->name, data);
|
||
+
|
||
+ if (head == NULL || *head == '\0') {
|
||
+ g_warning ("'shortname' format is different: %s", shortname);
|
||
+ g_free (head);
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
+ duplicated = g_slist_find_custom (data->annotations,
|
||
+ head,
|
||
+ (GCompareFunc) g_strcmp0);
|
||
+ if (duplicated == NULL) {
|
||
+ data->annotations = g_slist_prepend (data->annotations,
|
||
+ head);
|
||
} else {
|
||
- /* If annotate is NULL likes <td class="name"></td>,
|
||
- * the previous emoji cell has the same annotate.
|
||
- */
|
||
- if (g_strcmp0 ((const gchar *) node->name, "td") == 0 &&
|
||
- g_strcmp0 (data->class, "name") == 0) {
|
||
- data->annotates = g_slist_copy_deep (data->prev_annotates,
|
||
- (GCopyFunc) g_strdup,
|
||
- NULL);
|
||
+ g_free (head);
|
||
+ }
|
||
+
|
||
+#endif
|
||
+ return TRUE;
|
||
+}
|
||
+
|
||
+static gboolean
|
||
+parse_emojione_category (JsonNode *node,
|
||
+ EmojiData *data)
|
||
+{
|
||
+ const gchar *category;
|
||
+ GSList *duplicated;
|
||
+
|
||
+ if (json_node_get_node_type (node) != JSON_NODE_VALUE) {
|
||
+ g_warning ("'category' element is not string");
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
+ category = json_node_get_string (node);
|
||
+
|
||
+ if (category == NULL || *category == '\0')
|
||
+ return TRUE;
|
||
+
|
||
+ duplicated = g_slist_find_custom (data->annotations,
|
||
+ category,
|
||
+ (GCompareFunc) g_strcmp0);
|
||
+ if (duplicated == NULL) {
|
||
+ data->annotations = g_slist_prepend (data->annotations,
|
||
+ g_strdup (category));
|
||
+ }
|
||
+
|
||
+ return TRUE;
|
||
+}
|
||
+
|
||
+static gboolean
|
||
+parse_emojione_aliases_ascii (JsonNode *node,
|
||
+ EmojiData *data)
|
||
+{
|
||
+ JsonArray *aliases_ascii;
|
||
+ guint i, length;
|
||
+
|
||
+ if (json_node_get_node_type (node) != JSON_NODE_ARRAY) {
|
||
+ g_warning ("'aliases_ascii' element is not array");
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
+ aliases_ascii = json_node_get_array (node);
|
||
+ length = json_array_get_length (aliases_ascii);
|
||
+ for (i = 0; i < length; i++) {
|
||
+ const gchar *alias = json_array_get_string_element (aliases_ascii, i);
|
||
+ GSList *duplicated = g_slist_find_custom (data->annotations,
|
||
+ alias,
|
||
+ (GCompareFunc) g_strcmp0);
|
||
+ if (duplicated == NULL) {
|
||
+ data->annotations = g_slist_prepend (data->annotations,
|
||
+ g_strdup (alias));
|
||
}
|
||
}
|
||
- if (node->next)
|
||
- parse_node (node->next, FALSE, (const gchar *) node->name, data);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
-static GHashTable *
|
||
-parse_html (const gchar *filename)
|
||
+static gboolean
|
||
+parse_emojione_keywords (JsonNode *node,
|
||
+ EmojiData *data)
|
||
{
|
||
- xmlDoc *doc = htmlParseFile (filename, "utf-8");
|
||
- EmojiData data = { 0, };
|
||
+#if 0
|
||
+ JsonArray *keywords;
|
||
+ guint i, length;
|
||
|
||
- if (doc == NULL || doc->children == NULL) {
|
||
- g_warning ("Parse Error in document type: %x",
|
||
- doc ? doc->type : 0);
|
||
+ if (json_node_get_node_type (node) != JSON_NODE_ARRAY) {
|
||
+ g_warning ("'keywords' element is not array");
|
||
return FALSE;
|
||
}
|
||
|
||
- data.dict = g_hash_table_new_full (g_str_hash,
|
||
- g_str_equal,
|
||
- g_free,
|
||
- free_dict_words);
|
||
- parse_node (doc->children, TRUE, (const gchar *) doc->name, &data);
|
||
+ keywords = json_node_get_array (node);
|
||
+ length = json_array_get_length (keywords);
|
||
+ for (i = 0; i < length; i++) {
|
||
+ const gchar *keyword = json_array_get_string_element (keywords, i);
|
||
+ GSList *duplicated = g_slist_find_custom (data->annotations,
|
||
+ keyword,
|
||
+ (GCompareFunc) g_strcmp0);
|
||
+ if (duplicated == NULL) {
|
||
+ data->annotations = g_slist_prepend (data->annotations,
|
||
+ g_strdup (keyword));
|
||
+ }
|
||
+ }
|
||
|
||
+#endif
|
||
+ return TRUE;
|
||
+}
|
||
+
|
||
+static gboolean
|
||
+parse_emojione_emoji_data (JsonNode *node,
|
||
+ const gchar *member,
|
||
+ EmojiData *data)
|
||
+{
|
||
+ if (g_strcmp0 (member, "unicode") == 0)
|
||
+ return parse_emojione_unicode (node, data);
|
||
+ else if (g_strcmp0 (member, "shortname") == 0)
|
||
+ return parse_emojione_shortname (node, data);
|
||
+ else if (g_strcmp0 (member, "category") == 0)
|
||
+ return parse_emojione_category (node, data);
|
||
+ else if (g_strcmp0 (member, "aliases_ascii") == 0)
|
||
+ return parse_emojione_aliases_ascii (node, data);
|
||
+ else if (g_strcmp0 (member, "keywords") == 0)
|
||
+ return parse_emojione_keywords (node, data);
|
||
+ return TRUE;
|
||
+}
|
||
+
|
||
+static gboolean
|
||
+parse_emojione_element (JsonNode *node,
|
||
+ EmojiData *data)
|
||
+{
|
||
+ JsonObject *object;
|
||
+ GList *members, *m;
|
||
+
|
||
+ if (json_node_get_node_type (node) != JSON_NODE_OBJECT) {
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
+ reset_emoji_element (data);
|
||
+
|
||
+ object = json_node_get_object (node);
|
||
+ m = members = json_object_get_members (object);
|
||
+ while (m) {
|
||
+ const gchar *member = (const gchar *) m->data;
|
||
+ if (!parse_emojione_emoji_data (json_object_get_member (object, member),
|
||
+ member,
|
||
+ data)) {
|
||
+ g_list_free (members);
|
||
+ return FALSE;
|
||
+ }
|
||
+ m = m->next;
|
||
+ }
|
||
+ g_list_free (members);
|
||
+
|
||
+ update_emoji_dict (data);
|
||
+
|
||
+ return TRUE;
|
||
+}
|
||
+
|
||
+static gboolean
|
||
+emojione_parse_json_file (const gchar *filename,
|
||
+ GHashTable *dict)
|
||
+{
|
||
+ JsonParser *parser = json_parser_new ();
|
||
+ JsonNode *node;
|
||
+ JsonObject *object;
|
||
+ GList *members, *m;
|
||
+ GError *error = NULL;
|
||
+ EmojiData data = { 0, };
|
||
+
|
||
+ g_return_val_if_fail (filename != NULL, FALSE);
|
||
+ g_return_val_if_fail (dict != NULL, FALSE);
|
||
+
|
||
+ if (!json_parser_load_from_file (parser, filename, &error)) {
|
||
+ g_error ("%s", error->message);
|
||
+ g_error_free (error);
|
||
+ goto fail_to_json_file;
|
||
+ }
|
||
+
|
||
+ node = json_parser_get_root (parser);
|
||
+ if (json_node_get_node_type (node) != JSON_NODE_OBJECT) {
|
||
+ g_warning ("Json file does not have Json object %s", filename);
|
||
+ goto fail_to_json_file;
|
||
+ }
|
||
+
|
||
+ object = json_node_get_object (node);
|
||
+ members = json_object_get_members (object);
|
||
+ data.dict = dict;
|
||
+
|
||
+ m = members;
|
||
+ while (m) {
|
||
+ const gchar *member = (const gchar *) m->data;
|
||
+ if (!parse_emojione_element (json_object_get_member (object, member),
|
||
+ &data)) {
|
||
+ g_warning ("Failed to parse member '%s' in %s", member, filename);
|
||
+ }
|
||
+ m = m->next;
|
||
+ }
|
||
+
|
||
+ g_list_free (members);
|
||
reset_emoji_element (&data);
|
||
- g_slist_free_full (data.prev_annotates, g_free);
|
||
+ g_object_unref (parser);
|
||
+
|
||
+ return TRUE;
|
||
|
||
- return data.dict;
|
||
+fail_to_json_file:
|
||
+ g_object_unref (parser);
|
||
+ return FALSE;
|
||
}
|
||
|
||
int
|
||
main (int argc, char *argv[])
|
||
{
|
||
+ gchar *prgname;
|
||
+ gchar *json_file = NULL;
|
||
+ gchar *xml_file = NULL;
|
||
+ gchar *output = NULL;
|
||
+ GOptionEntry entries[] = {
|
||
+ { "json", 'j', 0, G_OPTION_ARG_STRING, &json_file,
|
||
+ "Parse Emoji One JSON file",
|
||
+ "JSON"
|
||
+ },
|
||
+ { "out", 'o', 0, G_OPTION_ARG_STRING, &output,
|
||
+ "Save the emoji dictionary as FILE",
|
||
+ "FILE"
|
||
+ },
|
||
+ { "xml", 'x', 0, G_OPTION_ARG_STRING, &xml_file,
|
||
+ "Parse Unocode.org ANNOTATIONS file",
|
||
+ "ANNOTATIONS"
|
||
+ },
|
||
+ { NULL }
|
||
+ };
|
||
+ GOptionContext *context;
|
||
+ GError *error = NULL;
|
||
GHashTable *dict;
|
||
- progname = basename (argv[0]);
|
||
+
|
||
+ prgname = g_path_get_basename (argv[0]);
|
||
+ g_set_prgname (prgname);
|
||
+ g_free (prgname);
|
||
+
|
||
+ context = g_option_context_new (NULL);
|
||
+ g_option_context_add_main_entries (context, entries, NULL);
|
||
|
||
if (argc < 3) {
|
||
- usage ();
|
||
+ g_print ("%s", g_option_context_get_help (context, TRUE, NULL));
|
||
+ g_option_context_free (context);
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
|
||
+ g_warning ("Failed options: %s", error->message);
|
||
+ g_error_free (error);
|
||
return -1;
|
||
}
|
||
+ g_option_context_free (context);
|
||
|
||
- dict = parse_html (argv[1]);
|
||
- ibus_emoji_dict_save (argv[2], dict);
|
||
+ dict = g_hash_table_new_full (g_str_hash,
|
||
+ g_str_equal,
|
||
+ g_free,
|
||
+ free_dict_words);
|
||
+ if (xml_file)
|
||
+ unicode_annotations_parse_xml_file (xml_file, dict);
|
||
+ if (json_file)
|
||
+ emojione_parse_json_file (json_file, dict);
|
||
+ if (g_hash_table_size (dict) > 0 && output)
|
||
+ ibus_emoji_dict_save (output, dict);
|
||
g_hash_table_destroy (dict);
|
||
|
||
return 0;
|
||
--
|
||
2.7.4
|
||
|
||
From f88c48750538eaaf7c7b182ba3763b45c2745074 Mon Sep 17 00:00:00 2001
|
||
From: fujiwarat <takao.fujiwara1@gmail.com>
|
||
Date: Wed, 20 Jul 2016 11:43:49 +0900
|
||
Subject: [PATCH 4/4] Fix typo in configure.ac
|
||
|
||
R=shawn.p.huang@gmail.com
|
||
|
||
Review URL: https://codereview.appspot.com/303110043
|
||
---
|
||
configure.ac | 2 +-
|
||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
||
diff --git a/configure.ac b/configure.ac
|
||
index f789819..76897f0 100644
|
||
--- a/configure.ac
|
||
+++ b/configure.ac
|
||
@@ -647,7 +647,7 @@ engine/Makefile
|
||
util/Makefile
|
||
util/IMdkit/Makefile
|
||
data/Makefile
|
||
-data/annotations/Makefile.am
|
||
+data/annotations/Makefile
|
||
data/icons/Makefile
|
||
data/keymaps/Makefile
|
||
data/dconf/Makefile
|
||
--
|
||
2.7.4
|
||
|