* Talkatu - GTK widgets for chat applications
* Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this library; if not, see <https://www.gnu.org/licenses/>.
#include "talkatu/talkatuactiongroup.h"
#include "talkatu/talkatutag.h"
#include "talkatu/talkatuenums.h"
* @Short_description: Helpers for handling tags.
* Talkatu deals with a lot of tags which this API tries to make easier.
* The standard _get_type macro for #TalkatuTag.
* A constant that represents an anchor or link font style.
* A constant for referencing the styling for an author.
* A constant that represents the bold font style.
* A constant that represents a code font style.
* A constant for the tag that tags message contents in a #TalkatuHistory
* A constant that represents the dd HTML element.
* A constant that represents the dl HTML element.
* A constant that reprensents the dt HTML element.
* TALKATU_TAG_FORMATTING_END:
* A constant to be used as a suffix for tags that need formatting applied
* after the original tag.
* TALKATU_TAG_FORMATTING_START:
* A constant to be used as a prefix for tags that need formatting applied
* before the original tag.
* A constant that represents the h1 header font style.
* A constant that represents the h2 header font style.
* A constant that represents the h3 header font style.
* A constant that represents the h4 header font style.
* A constant that represents the h5 header font style.
* A constant that represents the h6 header font style.
* A constant that represents the italic font style.
* A constant for the tag that tags an entire message in a #TalkatuHistory
* A constant that represents a preformatted font style.
* The prefix that all Talkatu tags use.
* TALKATU_TAG_PREFIX_LEN:
* The length of #TALKATU_TAG_PREFIX for easy computation.
* A constant that represents the highlighted search term font style.
* TALKATU_TAG_STRIKETHROUGH:
* A constant that represents the strikethrough font style.
* A constant that represents the sub-script font style.
* TALKATU_TAG_SUPERSCRIPT:
* A constant that represents the super-script font style.
* A constant that represents the timestamp font style.
* A constant that represents the underlined font style.
* @TALKATU_TAG_DISPLAY_INLINE: The tag should be rendered inline.
* @TALKATU_TAG_DISPLAY_BLOCK: The tag should be rendered on its own line.
* An enum representing how a tag should be rendered.
* TalkatuTag is a #GtkTextTag subclass that has a few additional properties
* that allows greater control of how text is rendered.
TalkatuTagDisplay display;
G_DEFINE_TYPE(TalkatuTag, talkatu_tag, GTK_TYPE_TEXT_TAG);
static GParamSpec *properties[N_PROPERTIES];
/******************************************************************************
*****************************************************************************/
talkatu_tag_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) {
TalkatuTag *tag = TALKATU_TAG(obj);
g_value_set_enum(value, talkatu_tag_get_display(tag));
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
talkatu_tag_set_property(GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec) {
TalkatuTag *tag = TALKATU_TAG(obj);
talkatu_tag_set_display(tag, g_value_get_enum(value));
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
talkatu_tag_init(TalkatuTag *tag) {
tag->display = TALKATU_TAG_DISPLAY_INLINE;
talkatu_tag_class_init(TalkatuTagClass *klass) {
GObjectClass *obj_class = G_OBJECT_CLASS(klass);
obj_class->get_property = talkatu_tag_get_property;
obj_class->set_property = talkatu_tag_set_property;
properties[PROP_DISPLAY] = g_param_spec_enum(
"display", "display", "How to display the text",
TALKATU_TYPE_TAG_DISPLAY,
TALKATU_TAG_DISPLAY_INLINE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT
g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
/******************************************************************************
*****************************************************************************/
* @name: The name to give the tag.
* @first_property: The name of the first property to set.
* @...: The value of the first property followed optionally by more name/value
* pairs, followed by NULL.
* Creates a new #TalkatuTag to be used for styling text.
* Returns: (transfer full): The new #TalkatuTag.
talkatu_tag_new(const gchar *name, const gchar *first_property, ...) {
g_return_val_if_fail(name != NULL, NULL);
va_start(vargs, first_property);
g_object_set_valist(G_OBJECT(tag), first_property, vargs);
* talkatu_tag_name_for_action_name:
* @action_name: The name of the action to find a tag name for.
* Gets the tag name that should be used for @action_name.
* Returns: The tag name to be used for @action_name, or %NULL.
talkatu_tag_name_for_action_name(const gchar *action_name) {
if(g_ascii_strcasecmp(action_name, TALKATU_ACTION_FORMAT_BOLD) == 0) {
} else if(g_ascii_strcasecmp(action_name, TALKATU_ACTION_FORMAT_ITALIC) == 0) {
return TALKATU_TAG_ITALIC;
} else if(g_ascii_strcasecmp(action_name, TALKATU_ACTION_FORMAT_UNDERLINE) == 0) {
return TALKATU_TAG_UNDERLINE;
} else if(g_ascii_strcasecmp(action_name, TALKATU_ACTION_FORMAT_STRIKETHROUGH) == 0) {
return TALKATU_TAG_STRIKETHROUGH;
* talkatu_tag_name_to_html:
* @tag_name: The name of the tag.
* Determines the HTML tag for @tag_name.
* Returns: The HTML tag if any for @tag_name.
talkatu_tag_name_to_html(const gchar *tag_name) {
if(g_ascii_strncasecmp(TALKATU_TAG_PREFIX, tag_name, TALKATU_TAG_PREFIX_LEN) != 0) {
if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_BOLD) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_ITALIC) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_UNDERLINE) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_STRIKETHROUGH) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_SUBSCRIPT) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_SUPERSCRIPT) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_PRE) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_H1) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_H2) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_H3) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_H4) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_H5) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_H6) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_ANCHOR) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_DL) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_DT) == 0) {
} else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_DD) == 0) {
* talkatu_tag_get_display:
* @tag: The #TalkatuTag instance.
* Gets the #TalkatuTagDisplay for @tag.
* Returns: The #TalkatuTagDisplay for @tag.
talkatu_tag_get_display(TalkatuTag *tag) {
g_return_val_if_fail(TALKATU_IS_TAG(tag), TALKATU_TAG_DISPLAY_INLINE);
* talkatu_tag_set_display:
* @tag: The #TalkatuTag instance.
* @display: The #TalkatuTagDisplay value to set.
* Sets the display type for @tag to @display.
talkatu_tag_set_display(TalkatuTag *tag, TalkatuTagDisplay display) {
g_return_if_fail(TALKATU_IS_TAG(tag));
g_object_notify_by_pspec(G_OBJECT(tag), properties[PROP_DISPLAY]);