[gspell/wip/apostrophe: 28/30] apostrophes: write _gspell_text_iter word-related functions
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gspell/wip/apostrophe: 28/30] apostrophes: write _gspell_text_iter word-related functions
- Date: Sat, 5 Mar 2016 17:49:02 +0000 (UTC)
commit 487eb71050ef436bc3cbab9231c9df02f8e050d5
Author: Sébastien Wilmet <swilmet gnome org>
Date: Fri Feb 12 16:09:32 2016 +0100
apostrophes: write _gspell_text_iter word-related functions
https://bugzilla.gnome.org/show_bug.cgi?id=131576
docs/reference/Makefile.am | 1 +
gspell/Makefile.am | 2 +
gspell/gspell-text-iter.c | 184 ++++++++++++++++++++++++++++++++++++++++++++
gspell/gspell-text-iter.h | 46 +++++++++++
po/POTFILES.in | 1 +
5 files changed, 234 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..bd47bbe
--- /dev/null
+++ b/gspell/gspell-text-iter.c
@@ -0,0 +1,184 @@
+/*
+ * 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 "doesn't", which is a
+ * contraction of the two words "does not".
+ *
+ * When to include an apostrophe in a word? The heuristic is that the apostrophe
+ * must be surrounded by a pango-defined word on *each* side of the apostrophe.
+ * In other words, there must be a word end on the left side and a word start on
+ * the right side.
+ *
+ * Note that with that rule, a word can contain several apostrophes, like
+ * "rock'n'roll". Usually such a word would be considered as misspelled, but
+ * it's important to take every apostrophes, otherwise the word boundaries would
+ * change depending on the GtkTextIter location, which would lead to bugs.
+ *
+ * Possible improvement: support words like "doin'" or "'til". That is, if the
+ * "internal" word ("doin" or "til") is surrounded by only one apostrophe, take
+ * the apostrophe. The implementation would be slightly more complicated, since
+ * a function behavior depends on the other side of the word.
+ *
+ * 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);
+
+ return ch == '\'';
+}
+
+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;
+ }
+
+ if (is_apostrophe (&prev_char) &&
+ gtk_text_iter_ends_word (&prev_char))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+_gspell_text_iter_ends_word (const GtkTextIter *iter)
+{
+ GtkTextIter next_char;
+
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ if (!gtk_text_iter_ends_word (iter))
+ {
+ return FALSE;
+ }
+
+ if (gtk_text_iter_is_end (iter))
+ {
+ return TRUE;
+ }
+
+ next_char = *iter;
+ gtk_text_iter_forward_char (&next_char);
+
+ if (is_apostrophe (iter) &&
+ gtk_text_iter_starts_word (&next_char))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+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]