qulogic/talkatu

a7fb35216eff
Parents b5f5b84c1209
Children 4f922f0ef658
move the html handling code to the new talkatumarkup.[ch]
--- a/talkatu/meson.build Tue Aug 21 22:12:11 2018 -0500
+++ b/talkatu/meson.build Tue Aug 21 22:46:51 2018 -0500
@@ -13,6 +13,7 @@
'talkatuhtmlbuffer.h',
'talkatulinkdialog.h',
'talkatumarkdownbuffer.h',
+ 'talkatumarkup.h',
'talkatumenutoolbutton.h',
'talkatumessage.h',
'talkatumessageactions.h',
@@ -32,6 +33,7 @@
'talkatuhtmlbuffer.c',
'talkatulinkdialog.c',
'talkatumarkdownbuffer.c',
+ 'talkatumarkup.c',
'talkatumenutoolbutton.c',
'talkatumessage.c',
'talkatumessageactions.c',
--- a/talkatu/talkatuhtmlbuffer.c Tue Aug 21 22:12:11 2018 -0500
+++ b/talkatu/talkatuhtmlbuffer.c Tue Aug 21 22:46:51 2018 -0500
@@ -16,13 +16,11 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <gumbo.h>
-#include <stdio.h>
-
#include "talkatu/talkatuaction.h"
#include "talkatu/talkatubuffer.h"
#include "talkatu/talkatucodeset.h"
#include "talkatu/talkatuhtmlbuffer.h"
+#include "talkatu/talkatumarkup.h"
#include "talkatu/talkatutag.h"
/**
@@ -37,183 +35,6 @@
G_DEFINE_TYPE(TalkatuHTMLBuffer, talkatu_html_buffer, TALKATU_TYPE_BUFFER);
/******************************************************************************
- * Helpers
- *****************************************************************************/
-static inline void
-talkatu_html_buffer_insert_text_parent(GtkTextBuffer *buffer,
- GtkTextIter *pos,
- const gchar *new_text)
-{
- talkatu_buffer_insert_markup(
- TALKATU_BUFFER(buffer),
- pos,
- new_text,
- g_utf8_strlen(new_text, -1)
- );
-}
-
-static gint
-talkatu_html_buffer_deserialize_helper(GtkTextBuffer *buffer,
- GtkTextIter *pos,
- GumboNode *node,
- GString *str)
-{
- GtkTextTag *tag = NULL;
- GumboVector *children = NULL;
- const gchar *tag_name = NULL;
- gint i = 0, start_pos, length = 0;
-
- start_pos = gtk_text_iter_get_offset(pos);
-
- switch(node->v.element.tag) {
- case GUMBO_TAG_B:
- tag_name = TALKATU_TAG_BOLD;
- break;
- case GUMBO_TAG_CODE:
- tag_name = TALKATU_TAG_CODE;
- break;
- case GUMBO_TAG_I:
- tag_name = TALKATU_TAG_ITALIC;
- break;
- case GUMBO_TAG_U:
- tag_name = TALKATU_TAG_UNDERLINE;
- break;
- case GUMBO_TAG_EM:
- break;
- case GUMBO_TAG_STRIKE:
- tag_name = TALKATU_TAG_STRIKETHROUGH;
- break;
- case GUMBO_TAG_SUB:
- tag_name = TALKATU_TAG_SUBSCRIPT;
- break;
- case GUMBO_TAG_SUP:
- tag_name = TALKATU_TAG_SUPERSCRIPT;
- break;
- case GUMBO_TAG_PRE:
- tag_name = TALKATU_TAG_PRE;
- break;
- default:
- break;
- }
-
- if(tag_name != NULL) {
- tag = gtk_text_tag_table_lookup(
- gtk_text_buffer_get_tag_table(buffer),
- tag_name
- );
- }
-
- children = &node->v.element.children;
-
- for(i = 0; i < children->length; i++) {
- GumboNode *child = (GumboNode *)children->data[i];
-
- if(child->type == GUMBO_NODE_TEXT || child->type == GUMBO_NODE_WHITESPACE) {
- gint text_length = g_utf8_strlen(child->v.text.text, -1);
-
- /* add the text */
- talkatu_html_buffer_insert_text_parent(buffer, pos, child->v.text.text);
-
- /* now adjust pos to the new insertion point */
- gtk_text_buffer_get_iter_at_offset(
- buffer,
- pos,
- gtk_text_iter_get_offset(pos) + text_length
- );
-
- length += text_length;
-
- } else if(child->type == GUMBO_NODE_ELEMENT || child->type == GUMBO_NODE_TEMPLATE) {
- length += talkatu_html_buffer_deserialize_helper(buffer, pos, child, str);
- }
- }
-
- if(tag) {
- GtkTextIter start, end;
-
- gtk_text_buffer_get_iter_at_offset(buffer, &start, start_pos);
- gtk_text_buffer_get_iter_at_offset(buffer, &end, start_pos + length);
-
- gtk_text_buffer_apply_tag(
- buffer,
- tag,
- &start,
- &end
- );
- }
-
- return length;
-}
-
-gboolean
-talkatu_html_buffer_deserialize(GtkTextBuffer *register_buffer,
- GtkTextBuffer *content_buffer,
- GtkTextIter *iter,
- const guint8 *data,
- gsize length,
- gboolean create_tags,
- gpointer user_data,
- GError **error)
-{
- GError *real_error = NULL;
- gchar *text = NULL;
- gsize text_length;
-
- text = talkatu_codeset_coerce_utf8(data, length, &text_length, &real_error);
- if(real_error) {
- if(error) {
- *error = real_error;
- }
-
- return FALSE;
- }
-
- talkatu_html_buffer_insert_html(
- TALKATU_HTML_BUFFER(register_buffer),
- iter,
- text,
- text_length
- );
-
- g_free(text);
-
- return TRUE;
-}
-
-/******************************************************************************
- * TalkatuHTMLBuffer Stuff
- *****************************************************************************/
-static void
-talkatu_html_buffer_real_insert_html(TalkatuHTMLBuffer *buffer,
- GtkTextIter *iter,
- const gchar *text,
- gint len)
-{
- GString *str = NULL;
- GumboOutput *output = NULL;
-
- output = gumbo_parse(text);
-
- str = g_string_new("");
- talkatu_html_buffer_deserialize_helper(
- GTK_TEXT_BUFFER(buffer),
- iter,
- output->document,
- str
- );
- gumbo_destroy_output(&kGumboDefaultOptions, output);
-
- talkatu_buffer_insert_markup(
- TALKATU_BUFFER(buffer),
- iter,
- str->str,
- str->len
- );
-
- g_string_free(str, TRUE);
-}
-
-/******************************************************************************
* GObject Stuff
*****************************************************************************/
static void
@@ -221,7 +42,7 @@
gtk_text_buffer_register_deserialize_format(
GTK_TEXT_BUFFER(buffer),
"text/html",
- talkatu_html_buffer_deserialize,
+ talkatu_markup_deserialize_html,
NULL,
NULL
);
@@ -229,7 +50,6 @@
static void
talkatu_html_buffer_class_init(TalkatuHTMLBufferClass *klass) {
- klass->insert_html = talkatu_html_buffer_real_insert_html;
}
/******************************************************************************
@@ -298,14 +118,9 @@
const gchar *text,
gint len)
{
- TalkatuHTMLBufferClass *klass = NULL;
-
g_return_if_fail(TALKATU_IS_HTML_BUFFER(buffer));
g_return_if_fail(iter != NULL);
g_return_if_fail(text != NULL);
- klass = TALKATU_HTML_BUFFER_GET_CLASS(buffer);
- if(klass && klass->insert_html) {
- klass->insert_html(buffer, iter, text, len);
- }
+ talkatu_markup_insert_html(TALKATU_BUFFER(buffer), iter, text, len);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/talkatumarkup.c Tue Aug 21 22:46:51 2018 -0500
@@ -0,0 +1,190 @@
+/*
+ * talkatu
+ * Copyright (C) 2017-2018 Gary Kramlich <grim@reaperworld.com>
+ *
+ * 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 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 <gumbo.h>
+
+#include "talkatu/talkatumarkup.h"
+
+/**
+ * SECTION:talkatumarkup
+ * @Title: Markup Helpers
+ * @Short_description: Helpers for reading/writing markup to GtkTextBuffers.
+ *
+ * This API provides the ability to serialize and deserialize mark to/from
+ * GtkTextBuffers.
+ */
+
+/******************************************************************************
+ * HTML
+ *****************************************************************************/
+static gint
+talkatu_markup_deserialize_html_helper(GtkTextBuffer *buffer,
+ GtkTextIter *pos,
+ GumboNode *node,
+ GString *str)
+{
+ GtkTextTag *tag = NULL;
+ GumboVector *children = NULL;
+ const gchar *tag_name = NULL;
+ gint i = 0, start_pos, length = 0;
+
+ start_pos = gtk_text_iter_get_offset(pos);
+
+ switch(node->v.element.tag) {
+ case GUMBO_TAG_B:
+ tag_name = TALKATU_TAG_BOLD;
+ break;
+ case GUMBO_TAG_CODE:
+ tag_name = TALKATU_TAG_CODE;
+ break;
+ case GUMBO_TAG_I:
+ tag_name = TALKATU_TAG_ITALIC;
+ break;
+ case GUMBO_TAG_U:
+ tag_name = TALKATU_TAG_UNDERLINE;
+ break;
+ case GUMBO_TAG_EM:
+ break;
+ case GUMBO_TAG_STRIKE:
+ tag_name = TALKATU_TAG_STRIKETHROUGH;
+ break;
+ case GUMBO_TAG_SUB:
+ tag_name = TALKATU_TAG_SUBSCRIPT;
+ break;
+ case GUMBO_TAG_SUP:
+ tag_name = TALKATU_TAG_SUPERSCRIPT;
+ break;
+ case GUMBO_TAG_PRE:
+ tag_name = TALKATU_TAG_PRE;
+ break;
+ default:
+ break;
+ }
+
+ if(tag_name != NULL) {
+ tag = gtk_text_tag_table_lookup(
+ gtk_text_buffer_get_tag_table(buffer),
+ tag_name
+ );
+ }
+
+ children = &node->v.element.children;
+
+ for(i = 0; i < children->length; i++) {
+ GumboNode *child = (GumboNode *)children->data[i];
+
+ if(child->type == GUMBO_NODE_TEXT || child->type == GUMBO_NODE_WHITESPACE) {
+ gint text_length = g_utf8_strlen(child->v.text.text, -1);
+
+ /* add the text */
+ talkatu_buffer_insert_markup(TALKATU_BUFFER(buffer), pos, child->v.text.text, -1);
+
+ /* now adjust pos to the new insertion point */
+ gtk_text_buffer_get_iter_at_offset(
+ buffer,
+ pos,
+ gtk_text_iter_get_offset(pos) + text_length
+ );
+
+ length += text_length;
+
+ } else if(child->type == GUMBO_NODE_ELEMENT || child->type == GUMBO_NODE_TEMPLATE) {
+ length += talkatu_markup_deserialize_html_helper(buffer, pos, child, str);
+ }
+ }
+
+ if(tag) {
+ GtkTextIter start, end;
+
+ gtk_text_buffer_get_iter_at_offset(buffer, &start, start_pos);
+ gtk_text_buffer_get_iter_at_offset(buffer, &end, start_pos + length);
+
+ gtk_text_buffer_apply_tag(
+ buffer,
+ tag,
+ &start,
+ &end
+ );
+ }
+
+ return length;
+}
+
+gboolean
+talkatu_markup_deserialize_html(GtkTextBuffer *register_buffer,
+ GtkTextBuffer *content_buffer,
+ GtkTextIter *iter,
+ const guint8 *data,
+ gsize length,
+ gboolean create_tags,
+ gpointer user_data,
+ GError **error)
+{
+ GError *real_error = NULL;
+ gchar *text = NULL;
+ gsize text_length;
+
+ text = talkatu_codeset_coerce_utf8(data, length, &text_length, &real_error);
+ if(real_error) {
+ if(error) {
+ *error = real_error;
+ }
+
+ return FALSE;
+ }
+
+ talkatu_html_buffer_insert_html(
+ TALKATU_HTML_BUFFER(register_buffer),
+ iter,
+ text,
+ text_length
+ );
+
+ g_free(text);
+
+ return TRUE;
+}
+
+void
+talkatu_markup_insert_html(TalkatuBuffer *buffer,
+ GtkTextIter *iter,
+ const gchar *text,
+ gint len)
+{
+ GString *str = NULL;
+ GumboOutput *output = NULL;
+
+ output = gumbo_parse(text);
+
+ str = g_string_new("");
+ talkatu_markup_deserialize_html_helper(
+ GTK_TEXT_BUFFER(buffer),
+ iter,
+ output->document,
+ str
+ );
+ gumbo_destroy_output(&kGumboDefaultOptions, output);
+
+ talkatu_buffer_insert_markup(
+ TALKATU_BUFFER(buffer),
+ iter,
+ str->str,
+ str->len
+ );
+
+ g_string_free(str, TRUE);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/talkatumarkup.h Tue Aug 21 22:46:51 2018 -0500
@@ -0,0 +1,40 @@
+/*
+ * talkatu
+ * Copyright (C) 2017-2018 Gary Kramlich <grim@reaperworld.com>
+ *
+ * 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 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 __GI_SCANNER__ /* hide this bit from g-ir-scanner */
+#if !defined(TALKATU_GLOBAL_HEADER_INSIDE) && !defined(TALKATU_COMPILATION)
+#error "only <talkatu.h> may be included directly"
+#endif
+#endif /* __GI_SCANNER__ */
+
+#ifndef TALKATU_MARKUP_H
+#define TALKATU_MARKUP_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <talkatu/talkatu.h>
+
+G_BEGIN_DECLS
+
+gboolean talkatu_markup_deserialize_html(GtkTextBuffer *register_buffer, GtkTextBuffer *content_buffer, GtkTextIter *iter, const guint8 *data, gsize length, gboolean create_tags, gpointer user_data, GError **error);
+void talkatu_markup_insert_html(TalkatuBuffer *buffer, GtkTextIter *iter, const gchar *text, gint len);
+
+G_END_DECLS
+
+#endif /* TALKATU_MARKUP_H */