[gspell/wip/apostrophe: 1/2] Support word contractions with apostrophes



commit 0cf68577bad8506093dcc5a99aa94faa9887a06b
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Fri Feb 12 16:09:32 2016 +0100

    Support word contractions with apostrophes
    
    https://bugzilla.gnome.org/show_bug.cgi?id=131576

 docs/reference/Makefile.am |    1 +
 gspell/Makefile.am         |    2 +
 gspell/gspell-text-iter.c  |  157 ++++++++++++++++++++++++++++++++++++++++++++
 gspell/gspell-text-iter.h  |   46 +++++++++++++
 po/POTFILES.in             |    1 +
 5 files changed, 207 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
index d81c64f..e27c6ef 100644
--- a/docs/reference/Makefile.am
+++ b/docs/reference/Makefile.am
@@ -23,6 +23,7 @@ IGNORE_HFILES =                                       \
        gspell-buffer-notifier.h                \
        gspell-inline-checker-text-buffer.h     \
        gspell-osx.h                            \
+       gspell-text-iter.h                      \
        gspell-text-region.h                    \
        gspell-utils.h
 
diff --git a/gspell/Makefile.am b/gspell/Makefile.am
index 1e6ddc3..80aba68 100644
--- a/gspell/Makefile.am
+++ b/gspell/Makefile.am
@@ -44,6 +44,7 @@ gspell_private_headers =                      \
        gconstructor.h                          \
        gspell-buffer-notifier.h                \
        gspell-inline-checker-text-buffer.h     \
+       gspell-text-iter.h                      \
        gspell-text-region.h                    \
        gspell-utils.h
 
@@ -51,6 +52,7 @@ gspell_private_c_files =                      \
        gspell-buffer-notifier.c                \
        gspell-init.c                           \
        gspell-inline-checker-text-buffer.c     \
+       gspell-text-iter.c                      \
        gspell-text-region.c                    \
        gspell-utils.c
 
diff --git a/gspell/gspell-text-iter.c b/gspell/gspell-text-iter.c
new file mode 100644
index 0000000..2bacf37
--- /dev/null
+++ b/gspell/gspell-text-iter.c
@@ -0,0 +1,157 @@
+/*
+ * This file is part of gspell, a spell-checking library.
+ *
+ * Copyright 2016 - Sébastien Wilmet <swilmet gnome org>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gspell-text-iter.h"
+
+/* The same functions as the gtk_text_iter_* equivalents, but take into account
+ * word contractions with an apostrophe. For example "don't", which is a
+ * contraction for the two words "do not".
+ *
+ * If there is an apostrophe at a word boundary, but without another word on the
+ * other side, then the apostrophe is not taken into account. For example for
+ * "'til" and "'sigma'", the words will be "til" and "sigma".
+ *
+ * If there are several apostrophes each directly surrounded by words, then it's
+ * taken as a single word. For example "rock'n'roll".
+ *
+ * If the following Pango bug is fixed, normally the gtk_text_iter_* functions
+ * can be used directly.
+ * FIXME: https://bugzilla.gnome.org/show_bug.cgi?id=97545
+ * "Make pango_default_break follow Unicode TR #29"
+ */
+
+static gboolean
+is_apostrophe (const GtkTextIter *iter)
+{
+       gunichar ch;
+
+       ch = gtk_text_iter_get_char (iter);
+
+       /* Single quote or apostrophe (U+2019 = 8217) */
+       return ch == '\'' || ch == 8217;
+}
+
+gboolean
+_gspell_text_iter_forward_word_end (GtkTextIter *iter)
+{
+       g_return_val_if_fail (iter != NULL, FALSE);
+
+       while (gtk_text_iter_forward_word_end (iter))
+       {
+               GtkTextIter next_char;
+
+               if (!is_apostrophe (iter))
+               {
+                       return TRUE;
+               }
+
+               next_char = *iter;
+               gtk_text_iter_forward_char (&next_char);
+
+               if (!gtk_text_iter_starts_word (&next_char))
+               {
+                       return TRUE;
+               }
+
+               *iter = next_char;
+       }
+
+       return FALSE;
+}
+
+gboolean
+_gspell_text_iter_backward_word_start (GtkTextIter *iter)
+{
+       g_return_val_if_fail (iter != NULL, FALSE);
+
+       while (gtk_text_iter_backward_word_start (iter))
+       {
+               GtkTextIter prev_char = *iter;
+
+               if (!gtk_text_iter_backward_char (&prev_char) ||
+                   !is_apostrophe (&prev_char) ||
+                   !gtk_text_iter_ends_word (&prev_char))
+               {
+                       return TRUE;
+               }
+
+               *iter = prev_char;
+       }
+
+       return FALSE;
+}
+
+gboolean
+_gspell_text_iter_starts_word (const GtkTextIter *iter)
+{
+       GtkTextIter prev_char;
+
+       g_return_val_if_fail (iter != NULL, FALSE);
+
+       if (!gtk_text_iter_starts_word (iter))
+       {
+               return FALSE;
+       }
+
+       prev_char = *iter;
+       if (!gtk_text_iter_backward_char (&prev_char))
+       {
+               return TRUE;
+       }
+
+       return (!is_apostrophe (&prev_char) ||
+               !gtk_text_iter_ends_word (&prev_char));
+}
+
+gboolean
+_gspell_text_iter_ends_word (const GtkTextIter *iter)
+{
+       g_return_val_if_fail (iter != NULL, FALSE);
+
+       if (!gtk_text_iter_ends_word (iter))
+       {
+               return FALSE;
+       }
+
+       return (!is_apostrophe (iter) ||
+               !gtk_text_iter_starts_word (iter));
+}
+
+gboolean
+_gspell_text_iter_inside_word (const GtkTextIter *iter)
+{
+       g_return_val_if_fail (iter != NULL, FALSE);
+
+       if (gtk_text_iter_inside_word (iter))
+       {
+               return TRUE;
+       }
+
+       if (gtk_text_iter_ends_word (iter) &&
+           is_apostrophe (iter))
+       {
+               GtkTextIter next_char = *iter;
+               gtk_text_iter_forward_char (&next_char);
+               return gtk_text_iter_starts_word (&next_char);
+       }
+
+       return FALSE;
+}
+
+/* ex:set ts=8 noet: */
diff --git a/gspell/gspell-text-iter.h b/gspell/gspell-text-iter.h
new file mode 100644
index 0000000..b344d43
--- /dev/null
+++ b/gspell/gspell-text-iter.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of gspell, a spell-checking library.
+ *
+ * Copyright 2016 - Sébastien Wilmet <swilmet gnome org>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GSPELL_TEXT_ITER_H__
+#define __GSPELL_TEXT_ITER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+G_GNUC_INTERNAL
+gboolean       _gspell_text_iter_forward_word_end      (GtkTextIter *iter);
+
+G_GNUC_INTERNAL
+gboolean       _gspell_text_iter_backward_word_start   (GtkTextIter *iter);
+
+G_GNUC_INTERNAL
+gboolean       _gspell_text_iter_starts_word           (const GtkTextIter *iter);
+
+G_GNUC_INTERNAL
+gboolean       _gspell_text_iter_ends_word             (const GtkTextIter *iter);
+
+G_GNUC_INTERNAL
+gboolean       _gspell_text_iter_inside_word           (const GtkTextIter *iter);
+
+G_END_DECLS
+
+#endif /* __GSPELL_TEXT_ITER_H__ */
+
+/* ex:set ts=8 noet: */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ea6ed5c..9cb374b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -12,6 +12,7 @@ gspell/gspell-navigator.c
 gspell/gspell-navigator-text-view.c
 gspell/gspell-osx.c
 gspell/gspell-text-buffer.c
+gspell/gspell-text-iter.c
 gspell/gspell-utils.c
 gspell/resources/checker-dialog.ui
 gspell/resources/language-dialog.ui


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]