diff --git a/goffice/canvas/goc-graph.c b/goffice/canvas/goc-graph.c
index ed84eb6..f7abec4 100644
--- a/goffice/canvas/goc-graph.c
+++ b/goffice/canvas/goc-graph.c
@@ -236,7 +236,6 @@ format_coordinate (GogAxis *axis, GOFormat *fmt, double x)
 		 go_font_metrics_unit,
 		 fmt,
 		 x, 'F', NULL,
-		 NULL,
 		 width, date_conv, TRUE);
 	if (err) {
 		/* Invalid number for format.  */
diff --git a/goffice/graph/gog-axis-line.c b/goffice/graph/gog-axis-line.c
index da30abc..ba08b88 100644
--- a/goffice/graph/gog-axis-line.c
+++ b/goffice/graph/gog-axis-line.c
@@ -1268,7 +1268,7 @@ axis_line_render (GogAxisBase *axis_base,
 			label_pos.x = obrs[j].x;
 			label_pos.y = obrs[j].y;
 			gog_renderer_draw_text (renderer, ticks[j].label,
-						&label_pos, GTK_ANCHOR_CENTER,
+						&label_pos, GTK_ANCHOR_CENTER, NULL,
 						TRUE);
 		}
 	}
@@ -1475,7 +1475,7 @@ axis_circle_render (GogAxisBase *axis_base, GogRenderer *renderer,
 			    (!go_geometry_test_OBR_overlap (&txt_obr, &txt_obr_old) &&
 			     !go_geometry_test_OBR_overlap (&txt_obr, &txt_obr_first))) {
 				gog_renderer_draw_text (renderer, ticks[i].label,
-							&label_pos, GTK_ANCHOR_CENTER, TRUE);
+							&label_pos, GTK_ANCHOR_CENTER, NULL, TRUE);
 				txt_obr_old = txt_obr;
 			}
 			if (!first_label_done) {
diff --git a/goffice/graph/gog-axis.c b/goffice/graph/gog-axis.c
index 4762c67..924633d 100644
--- a/goffice/graph/gog-axis.c
+++ b/goffice/graph/gog-axis.c
@@ -116,6 +116,8 @@ create_invalid_axis_ticks (double min, double max)
 	ticks[0].type = ticks[1].type = GOG_AXIS_TICK_MAJOR;
 	ticks[0].label = g_strdup ("##");
 	ticks[1].label = g_strdup ("##");
+	ticks[0].attrs = NULL;
+	ticks[1].attrs = NULL;
 
 	return ticks;
 }
@@ -151,7 +153,6 @@ axis_format_value (GogAxis *axis, double val)
 		 go_font_metrics_unit,
 		 fmt,
 		 val, 'F', NULL,
-		 NULL,
 		 -1, date_conv, TRUE);
 	if (err) {
 		/* Invalid number for format.  */
@@ -346,6 +347,7 @@ map_discrete_calc_ticks (GogAxis *axis)
 		ticks[i].position = tick_start + (double) (i) * major_tick;
 		ticks[i].type = GOG_AXIS_TICK_MAJOR;
 		ticks[i].label = NULL;
+		ticks[i].attrs = NULL;
 	}
 	for (i = 0, j = tick_nbr; i < label_nbr; i++, j++) {
 		ticks[j].position = go_rint (label_start + (double) (i) * major_label);
@@ -762,6 +764,7 @@ map_linear_calc_ticks (GogAxis *axis)
 			ticks[t].position = maj_pos;
 			ticks[t].type = GOG_AXIS_TICK_MAJOR;
 			ticks[t].label = axis_format_value (axis, maj_pos);
+			ticks[t].attrs = NULL;
 			t++;
 		}
 
@@ -986,6 +989,7 @@ map_date_calc_ticks (GogAxis *axis)
 		ticks[t].position = maj_pos;
 		ticks[t].type = GOG_AXIS_TICK_MAJOR;
 		ticks[t].label = axis_format_value (axis, maj_pos);
+		ticks[t].attrs = NULL;
 		t++;
 
 		/* Calculate next major so we know when to stop minors.  */
@@ -1350,6 +1354,7 @@ map_log_calc_ticks (GogAxis *axis)
 			ticks[t].position = maj_pos;
 			ticks[t].type = GOG_AXIS_TICK_MAJOR;
 			ticks[t].label = axis_format_value (axis, maj_pos);
+			ticks[t].attrs = NULL;
 			t++;
 		}
 
@@ -1777,8 +1782,10 @@ gog_axis_set_ticks (GogAxis *axis, int tick_nbr, GogAxisTick *ticks)
 	g_return_if_fail (GOG_IS_AXIS (axis));
 
 	if (axis->ticks != NULL) {
-		for (i = 0; i < axis->tick_nbr; i++)
+		for (i = 0; i < axis->tick_nbr; i++) {
 			g_free (axis->ticks[i].label);
+			pango_attr_list_unref (axis->ticks[i].attrs);
+		}
 
 		g_free (axis->ticks);
 	}
diff --git a/goffice/graph/gog-axis.h b/goffice/graph/gog-axis.h
index 75c5b6e..b2e647c 100644
--- a/goffice/graph/gog-axis.h
+++ b/goffice/graph/gog-axis.h
@@ -46,6 +46,7 @@ typedef struct {
 	double		 position;
 	GogAxisTickTypes	 type;
 	char 		*label;
+	PangoAttrList   *attrs;
 } GogAxisTick;
 
 typedef struct _GogAxisMap GogAxisMap;
diff --git a/goffice/graph/gog-label.c b/goffice/graph/gog-label.c
index 7c58595..947286b 100644
--- a/goffice/graph/gog-label.c
+++ b/goffice/graph/gog-label.c
@@ -475,7 +475,8 @@ gog_text_view_render (GogView *view, GogViewAllocation const *bbox)
 			gog_renderer_draw_rectangle (view->renderer, &rect);
 		}
 		gog_renderer_draw_text (view->renderer, str,
-					&view->residual, GTK_ANCHOR_NW, FALSE);
+					&view->residual, GTK_ANCHOR_NW, 
+					NULL, FALSE);
 		g_free (str);
 	}
 	gog_renderer_pop_style (view->renderer);
diff --git a/goffice/graph/gog-legend.c b/goffice/graph/gog-legend.c
index 4a69ece..d74dd07 100644
--- a/goffice/graph/gog-legend.c
+++ b/goffice/graph/gog-legend.c
@@ -511,7 +511,7 @@ cb_render_elements (unsigned index, GOStyle const *base_style, char const *name,
 	pos.x = data->x + glv->label_offset;
 	pos.y = data->y + glv->element_height / 2.0;
 	pos.w = pos.h = -1;
-	gog_renderer_draw_text (renderer, name, &pos, GTK_ANCHOR_W, FALSE);
+	gog_renderer_draw_text (renderer, name, &pos, GTK_ANCHOR_W, NULL, FALSE);
 
 	if (style != base_style && style != NULL)
 		g_object_unref (style);
diff --git a/goffice/graph/gog-renderer.c b/goffice/graph/gog-renderer.c
index 17a32ee..f0d1a66 100644
--- a/goffice/graph/gog-renderer.c
+++ b/goffice/graph/gog-renderer.c
@@ -782,6 +782,8 @@ gog_renderer_draw_marker (GogRenderer *rend, double x, double y)
  * @text   : the string to draw
  * @pos    : #GogViewAllocation
  * @anchor : #GtkAnchorType how to draw relative to @pos
+ * @attrs  : Opptional attributes used when @use_markup==FALSE
+ *           The reference remains with the caller
  * @use_markup: wether to use pango markup
  *
  * Have @rend draw @text in the at @pos.{x,y} anchored by the @anchor corner.
@@ -791,6 +793,7 @@ gog_renderer_draw_marker (GogRenderer *rend, double x, double y)
 void
 gog_renderer_draw_text (GogRenderer *rend, char const *text,
 			GogViewAllocation const *pos, GtkAnchorType anchor,
+			PangoAttrList *attrs,
 			gboolean use_markup)
 {
 	PangoLayout *layout;
@@ -813,11 +816,13 @@ gog_renderer_draw_text (GogRenderer *rend, char const *text,
 	layout = pango_cairo_create_layout (cairo);
 	context = pango_layout_get_context (layout);
 	pango_cairo_context_set_resolution (context, 72.0);
+	pango_layout_set_font_description (layout, style->font.font->desc);
 	if (use_markup)
 		pango_layout_set_markup (layout, text, -1);
-	else
+	else {
 		pango_layout_set_text (layout, text, -1);
-	pango_layout_set_font_description (layout, style->font.font->desc);
+		pango_layout_set_attributes (layout, attrs);
+	}
 	pango_layout_get_size (layout, &iw, &ih);
 
 	obr.w = rend->scale * ((double) iw + (double) PANGO_SCALE / 2.0) / (double) PANGO_SCALE;
diff --git a/goffice/graph/gog-renderer.h b/goffice/graph/gog-renderer.h
index 3c0dc5e..378a6e2 100644
--- a/goffice/graph/gog-renderer.h
+++ b/goffice/graph/gog-renderer.h
@@ -115,7 +115,8 @@ void  gog_renderer_draw_selection_rectangle	(GogRenderer *renderer, GogViewAlloc
 void  gog_renderer_draw_marker	  (GogRenderer *rend, double x, double y);
 
 void  gog_renderer_draw_text	  (GogRenderer *rend, char const *text,
-				   GogViewAllocation const *pos, GtkAnchorType anchor,
+				   GogViewAllocation const *pos, 
+				   GtkAnchorType anchor, PangoAttrList *attrs,
 				   gboolean use_markup);
 
 void  gog_renderer_get_text_OBR   (GogRenderer *rend, char const *text,
diff --git a/goffice/gtk/go-format-sel.c b/goffice/gtk/go-format-sel.c
index c0c4224..2b7b9d7 100644
--- a/goffice/gtk/go-format-sel.c
+++ b/goffice/gtk/go-format-sel.c
@@ -160,12 +160,12 @@ static guint go_format_sel_signals [LAST_SIGNAL] = { 0 };
 static void format_entry_set_text (GOFormatSel *gfs, const gchar *text);
 
 static char *
-generate_preview (GOFormatSel *gfs, GOColor *c)
+generate_preview (GOFormatSel *gfs, PangoAttrList **attrs)
 {
 	char *res = NULL;
 	g_signal_emit (G_OBJECT (gfs),
 		       go_format_sel_signals [GENERATE_PREVIEW], 0,
-		       c, &res);
+		       attrs, &res);
 	return res;
 }
 
@@ -174,8 +174,7 @@ draw_format_preview (GOFormatSel *gfs, gboolean regen_format)
 {
 	char *preview;
 	GOFormat const *sf = NULL;
-	GOColor c = 0;
-	GdkColor gdk_color;
+	PangoAttrList *attrs = NULL;
 	gsize len;
 
 	if (regen_format) {
@@ -196,22 +195,23 @@ draw_format_preview (GOFormatSel *gfs, gboolean regen_format)
 	if (NULL == (sf = gfs->format.spec))
 		return;
 
-	if (NULL == (preview = generate_preview (gfs, &c)))
+	if (NULL == (preview = generate_preview (gfs, &attrs)))
 		return;
 
 	len = g_utf8_strlen (preview, -1);
 	if (len > FORMAT_PREVIEW_MAX)
-		strcpy (g_utf8_offset_to_pointer (preview, FORMAT_PREVIEW_MAX - 5),
+		strcpy (g_utf8_offset_to_pointer (preview, 
+						  FORMAT_PREVIEW_MAX - 5),
 			"...");
 
 	gtk_text_buffer_set_text (gfs->format.preview_buffer, preview, -1);
-	if (c != 0)
-		go_color_to_gdk (c, &gdk_color);
-	else
-		gdk_color_parse ("black", &gdk_color);
 
-	gtk_widget_modify_text (GTK_WIDGET (gfs->format.preview),
-				GTK_STATE_NORMAL, &gdk_color);
+	go_load_pango_attributes_into_buffer (attrs, 
+					      gfs->format.preview_buffer,
+					      preview);
+
+	pango_attr_list_unref (attrs);
+
 	g_free (preview);
 }
 
@@ -999,6 +999,7 @@ nfs_init (GOFormatSel *gfs)
 		pango_font_metrics_unref (metrics);
 	}
 	gfs->format.preview_buffer = gtk_text_view_get_buffer (gfs->format.preview);
+	go_create_std_tags_for_buffer (gfs->format.preview_buffer);
 
 	gfs->format.menu = go_gtk_builder_get_widget (gfs->gui, "format_menu");
 	populate_menu (gfs);
diff --git a/goffice/utils/go-format.c b/goffice/utils/go-format.c
index 6c62419..48ae59d 100644
--- a/goffice/utils/go-format.c
+++ b/goffice/utils/go-format.c
@@ -179,6 +179,8 @@ typedef enum {
 	OP_NUM_MARK_MANTISSA,
 	OP_NUM_SIMPLIFY_MANTISSA,
 	OP_NUM_SIMPLIFY_EXPONENT,
+	OP_MARKUP_SUPERSCRIPT_START,
+	OP_MARKUP_SUPERSCRIPT_END,
 #endif
 	OP_NUM_FRACTION,	/* wholep explicitp (digits|denominator) */
 	OP_NUM_FRACTION_WHOLE,
@@ -1769,11 +1771,7 @@ go_format_parse_number_E (GOFormatParseState *pstate)
 			ADD_OP (OP_NUM_SIMPLIFY_MANTISSA);
 		ADD_OP2 (OP_CHAR, '1');
 		ADD_OP2 (OP_CHAR, '0');
-		ADD_OP2 (OP_CHAR, '<');
-		ADD_OP2 (OP_CHAR, 's');
-		ADD_OP2 (OP_CHAR, 'u');
-		ADD_OP2 (OP_CHAR, 'p');
-		ADD_OP2 (OP_CHAR, '>');
+		ADD_OP  (OP_MARKUP_SUPERSCRIPT_START);
 	} else
 #endif
 		ADD_OP2 (OP_CHAR, 'E');
@@ -1785,14 +1783,9 @@ go_format_parse_number_E (GOFormatParseState *pstate)
 
 #ifdef ALLOW_EE_MARKUP
 	if (use_markup) {
-		ADD_OP2 (OP_CHAR, '<');
-		ADD_OP2 (OP_CHAR, '/');
-		ADD_OP2 (OP_CHAR, 's');
-		ADD_OP2 (OP_CHAR, 'u');
-		ADD_OP2 (OP_CHAR, 'p');
-		ADD_OP2 (OP_CHAR, '>');
 		if (simplify_mantissa)
 			ADD_OP (OP_NUM_SIMPLIFY_EXPONENT);
+		ADD_OP  (OP_MARKUP_SUPERSCRIPT_END);
 	}
 #endif
 
@@ -2315,6 +2308,8 @@ go_format_dump_program (const guchar *prg)
 		REGULAR(OP_NUM_MARK_MANTISSA);
 		REGULAR(OP_NUM_SIMPLIFY_MANTISSA);
 		REGULAR(OP_NUM_SIMPLIFY_EXPONENT);
+		REGULAR(OP_MARKUP_SUPERSCRIPT_START);
+		REGULAR(OP_MARKUP_SUPERSCRIPT_END);
 #endif
 		REGULAR(OP_NUM_FRACTION_WHOLE);
 		REGULAR(OP_NUM_FRACTION_NOMINATOR);
@@ -2497,11 +2492,19 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
 		DOUBLE w, n, d;
 		gsize nominator_start, denominator_start;
 	} fraction;
+	char *oldlocale = NULL;
 #ifdef ALLOW_EE_MARKUP
 	int mantissa_start = -1;
 	int special_mantissa = INT_MAX;
+	PangoAttrList *attrs = NULL;
+	GSList *markup_stack = NULL;
+
+	if (layout) {
+		attrs = pango_attr_list_copy (pango_layout_get_attributes (layout));
+		if (attrs == NULL)
+			attrs = pango_attr_list_new ();
+	}
 #endif
-	char *oldlocale = NULL;
 
 	memset (&fraction, 0, sizeof (fraction));
 
@@ -2510,8 +2513,15 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
 
 		switch (op) {
 		case OP_END:
-			if (layout)
+			if (layout) {
 				pango_layout_set_text (layout, dst->str, -1);
+#ifdef ALLOW_EE_MARKUP
+
+				pango_layout_set_attributes (layout, attrs);
+				pango_attr_list_unref (attrs);
+				g_slist_free (markup_stack);
+#endif
+			}
 			if (numtxt)
 				g_string_free (numtxt, TRUE);
 			if (oldlocale) {
@@ -3062,6 +3072,33 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
 				g_string_append_c (dst, '0');
 			}
 			break;
+
+		case OP_MARKUP_SUPERSCRIPT_START:
+			if (layout)
+				markup_stack = g_slist_prepend 
+					(markup_stack, GSIZE_TO_POINTER (dst->len));
+			break;
+
+		case OP_MARKUP_SUPERSCRIPT_END: 
+			if (layout) {
+				guint start = 0, 
+					end = (guint)dst->len;
+				PangoAttribute *attr;
+				if (markup_stack) {
+					start = (guint)GPOINTER_TO_SIZE (markup_stack->data);
+					markup_stack = g_slist_delete_link (markup_stack, markup_stack);
+				}
+				 /* FIXME: we need to calculate the right rise value */
+				attr = pango_attr_rise_new (5000);
+				attr->start_index = start;
+				attr->end_index = end;
+				pango_attr_list_insert (attrs, attr);
+				attr = pango_attr_scale_new (PANGO_SCALE_SMALL);
+				attr->start_index = start;
+				attr->end_index = end;
+				pango_attr_list_insert (attrs, attr);
+			}
+			break;
 #endif
 
 		case OP_NUM_FRACTION: {
@@ -3451,6 +3488,7 @@ SUFFIX(go_render_general) (PangoLayout *layout, GString *str,
 	return;
 }
 
+#define FREE_NEW_STR do { if (new_str) (void)g_string_free (new_str, TRUE); } while (0)
 
 GOFormatNumberError
 SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
@@ -3458,25 +3496,40 @@ SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
 				 const GOFontMetrics *metrics,
 				 GOFormat const *fmt,
 				 DOUBLE val, char type, const char *sval,
-				 GOColor *go_color,
 				 int col_width,
 				 GODateConventions const *date_conv,
 				 gboolean unicode_minus)
 {
 	gboolean inhibit = FALSE;
+	GString *new_str =  NULL;
+	GOFormatNumberError err;
 
 	g_return_val_if_fail (type == 'F' || sval != NULL,
 			      (GOFormatNumberError)-1);
 
-	g_string_truncate (str, 0);
+	if (str == NULL)
+		new_str = str = g_string_new (NULL);
+	else
+		g_string_truncate (str, 0);
 
 	if (fmt)
 		fmt = SUFFIX(go_format_specialize) (fmt, val, type, &inhibit);
 	if (!fmt)
 		fmt = go_format_general ();
 
-	if (go_color)
-		*go_color = fmt->color;
+	if (layout && fmt->color != 0) {
+		PangoAttrList *attrs;
+		PangoAttribute *attr;
+		attrs = pango_attr_list_ref (pango_layout_get_attributes (layout));
+		if (attrs == NULL)
+			attrs = pango_attr_list_new ();
+		attr = go_color_to_pango (fmt->color, TRUE);
+		attr->start_index = 0;
+		attr->end_index = G_MAXUINT;
+		pango_attr_list_insert (attrs, attr);
+		pango_layout_set_attributes (layout, attrs);
+		pango_attr_list_unref (attrs);
+	}
 
 	if (type == 'F') {
 		switch (fmt->typ) {
@@ -3487,14 +3540,17 @@ SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
 				(layout, str, measure, metrics,
 				 val,
 				 col_width, unicode_minus);
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_OK;
 
 		case GO_FMT_NUMBER:
 			if (val < 0) {
 #ifndef ALLOW_NEGATIVE_TIMES
 				if (fmt->u.number.has_date ||
-				    fmt->u.number.has_time)
+				    fmt->u.number.has_time) {
+					FREE_NEW_STR;
 					return GO_FORMAT_NUMBER_DATE_ERROR;
+				}
 #endif
 				if (inhibit)
 					val = SUFFIX(fabs)(val);
@@ -3503,16 +3559,20 @@ SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
 			g_printerr ("Executing %s\n", fmt->format);
 			go_format_dump_program (fmt->u.number.program);
 #endif
-			return SUFFIX(go_format_execute)
+
+			err = SUFFIX(go_format_execute)
 				(layout, str,
 				 measure, metrics,
 				 fmt->u.number.program,
 				 col_width,
 				 val, sval, date_conv,
 				 unicode_minus);
-
+			FREE_NEW_STR;
+			return err;
+			
 		case GO_FMT_EMPTY:
 			SETUP_LAYOUT;
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_OK;
 
 		default:
@@ -3520,26 +3580,30 @@ SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
 		case GO_FMT_MARKUP:
 		case GO_FMT_COND:
 			SETUP_LAYOUT;
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_INVALID_FORMAT;
 		}
 	} else {
 		switch (fmt->typ) {
 		case GO_FMT_TEXT:
-			return SUFFIX(go_format_execute)
+			err = SUFFIX(go_format_execute)
 				(layout, str,
 				 measure, metrics,
 				 fmt->u.text.program,
 				 col_width,
 				 val, sval, date_conv,
 				 unicode_minus);
-
+			FREE_NEW_STR;
+			return err;
 		case GO_FMT_NUMBER:
 			g_string_assign (str, sval);
 			SETUP_LAYOUT;
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_OK;
 
 		case GO_FMT_EMPTY:
 			SETUP_LAYOUT;
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_OK;
 
 		default:
@@ -3547,11 +3611,14 @@ SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
 		case GO_FMT_MARKUP:
 		case GO_FMT_COND:
 			SETUP_LAYOUT;
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_INVALID_FORMAT;
 		}
 	}
 }
 
+#undef FREE_NEW_STR
+
 /**
  * go_format_value:
  * @fmt: a #GOFormat
@@ -3572,7 +3639,6 @@ SUFFIX(go_format_value) (GOFormat const *fmt, DOUBLE val)
 		 go_font_metrics_unit,
 		 fmt,
 		 val, 'F', NULL,
-		 NULL,
 		 -1, NULL, FALSE);
 	if (err) {
 		/* Invalid number for format.  */
diff --git a/goffice/utils/go-format.h b/goffice/utils/go-format.h
index b82e3b3..f3d2e78 100644
--- a/goffice/utils/go-format.h
+++ b/goffice/utils/go-format.h
@@ -195,7 +195,6 @@ go_format_value_gstring (PangoLayout *layout, GString *str,
 			 const GOFontMetrics *metrics,
 			 GOFormat const *fmt,
 			 double val, char type, const char *sval,
-			 GOColor *go_color,
 			 int col_width,
 			 GODateConventions const *date_conv,
 			 gboolean unicode_minus);
@@ -207,7 +206,6 @@ go_format_value_gstringl (PangoLayout *layout, GString *str,
 			  const GOFontMetrics *metrics,
 			  GOFormat const *fmt,
 			  long double val, char type, const char *sval,
-			  GOColor *go_color,
 			  int col_width,
 			  GODateConventions const *date_conv,
 			  gboolean unicode_minus);
diff --git a/goffice/utils/go-pango-extras.c b/goffice/utils/go-pango-extras.c
index 9b6e677..0097cf9 100644
--- a/goffice/utils/go-pango-extras.c
+++ b/goffice/utils/go-pango-extras.c
@@ -1,3 +1,4 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * go-pango-extras.c: Various utility routines that should have been in pango.
  *
@@ -7,6 +8,8 @@
 
 #include <goffice/goffice-config.h>
 #include "go-pango-extras.h"
+#include "go-glib-extras.h"
+#include <string.h>
 
 struct cb_splice {
 	guint pos, len;
@@ -244,3 +247,233 @@ go_pango_attr_list_is_empty (const PangoAttrList *attrs)
 					      cb_empty, &empty);
 	return empty;
 }
+
+static gboolean
+go_load_pango_attributes_into_buffer_filter (PangoAttribute *attribute,
+					  G_GNUC_UNUSED gpointer data)
+{
+	return ((PANGO_ATTR_FOREGROUND == attribute->klass->type) ||
+		(PANGO_ATTR_UNDERLINE == attribute->klass->type) ||
+		(PANGO_ATTR_RISE == attribute->klass->type));
+}
+
+static gboolean
+go_load_pango_attributes_into_buffer_named_filter (PangoAttribute *attribute,
+						    G_GNUC_UNUSED gpointer data)
+{
+	return ((PANGO_ATTR_STYLE == attribute->klass->type) ||
+		(PANGO_ATTR_WEIGHT == attribute->klass->type) ||
+		(PANGO_ATTR_STRIKETHROUGH == attribute->klass->type));
+}
+
+void
+go_create_std_tags_for_buffer (GtkTextBuffer *buffer)
+{
+	gtk_text_buffer_create_tag (buffer, "PANGO_STYLE_NORMAL", "style", PANGO_STYLE_NORMAL,
+				    "style-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_STYLE_ITALIC", "style", PANGO_STYLE_ITALIC,
+				    "style-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_STRIKETHROUGH_TRUE", "strikethrough", TRUE,
+				    "strikethrough-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_STRIKETHROUGH_FALSE", "strikethrough", FALSE,
+				    "strikethrough-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_THIN", "weight", 100,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_ULTRALIGHT", "weight", PANGO_WEIGHT_ULTRALIGHT,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_LIGHT", "weight", PANGO_WEIGHT_LIGHT,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_BOOK", "weight", 380,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_NORMAL", "weight", PANGO_WEIGHT_NORMAL,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_MEDIUM", "weight", 500,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_SEMIBOLD", "weight", PANGO_WEIGHT_SEMIBOLD,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_BOLD", "weight", PANGO_WEIGHT_BOLD,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_ULTRABOLD", "weight", PANGO_WEIGHT_ULTRABOLD,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_HEAVY", "weight", PANGO_WEIGHT_HEAVY,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_ULTRAHEAVY", "weight", 1000,
+				    "weight-set", TRUE, NULL);
+}
+
+static gint
+go_load_pango_byte_to_char (gchar const *str, gint byte)
+{
+	if (byte >= (gint)strlen (str))
+		return g_utf8_strlen (str, -1);
+	return g_utf8_pointer_to_offset (str, g_utf8_prev_char (str + byte + 1));
+}
+
+void
+go_load_pango_attributes_into_buffer (PangoAttrList  *markup, GtkTextBuffer *buffer, gchar const *str)
+{
+	PangoAttrIterator * iter;
+	PangoAttrList  *copied_markup;
+	PangoAttrList  *our_markup;
+
+	if (markup == NULL)
+		return;
+
+/* For some styles we create named tags. The names are taken from the Pango enums */
+
+	copied_markup = pango_attr_list_copy (markup);
+	our_markup = pango_attr_list_filter (copied_markup,
+					     go_load_pango_attributes_into_buffer_named_filter,
+					     NULL);
+	pango_attr_list_unref (copied_markup);
+	if (our_markup != NULL) {
+		iter = pango_attr_list_get_iterator (our_markup);
+
+		do {
+			GSList *attr = pango_attr_iterator_get_attrs (iter);
+			if (attr != NULL) {
+				GSList *ptr;
+				gint start, end;
+				GtkTextIter start_iter, end_iter;
+				char const *name;
+
+				pango_attr_iterator_range (iter, &start, &end);
+				start = go_load_pango_byte_to_char (str, start);
+				end = go_load_pango_byte_to_char (str, end);
+				gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
+				gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);
+
+				for (ptr = attr; ptr != NULL; ptr = ptr->next) {
+					PangoAttribute *attribute = ptr->data;
+					GtkTextTag *tag;
+					int val;
+
+					switch (attribute->klass->type) {
+					case PANGO_ATTR_STYLE:
+						name = (((PangoAttrInt *)attribute)->value
+							== PANGO_STYLE_NORMAL)
+							? "PANGO_STYLE_NORMAL" :
+							"PANGO_STYLE_ITALIC";
+						tag = gtk_text_tag_table_lookup
+							(gtk_text_buffer_get_tag_table (buffer),
+							 name);
+						gtk_text_buffer_apply_tag (buffer, tag,
+									   &start_iter, &end_iter);
+						break;
+					case PANGO_ATTR_STRIKETHROUGH:
+						name = (((PangoAttrInt *)attribute)->value) ?
+							"PANGO_STRIKETHROUGH_TRUE" :
+							"PANGO_STRIKETHROUGH_FALSE";
+						tag = gtk_text_tag_table_lookup
+							(gtk_text_buffer_get_tag_table (buffer),
+							 name);
+						gtk_text_buffer_apply_tag (buffer, tag,
+									   &start_iter, &end_iter);
+						break;
+					case PANGO_ATTR_WEIGHT:
+						val = ((PangoAttrInt *)attribute)->value;
+						if (val < (PANGO_WEIGHT_THIN + PANGO_WEIGHT_ULTRALIGHT)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_THIN",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_ULTRALIGHT",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_BOOK)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_LIGHT",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_BOOK + PANGO_WEIGHT_NORMAL)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_BOOK",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_MEDIUM)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_NORMAL",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_MEDIUM + PANGO_WEIGHT_SEMIBOLD)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_MEDIUM",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_SEMIBOLD + PANGO_WEIGHT_BOLD)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_SEMIBOLD",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_BOLD",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_ULTRABOLD + PANGO_WEIGHT_HEAVY)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_ULTRABOLD",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_HEAVY + PANGO_WEIGHT_ULTRAHEAVY)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_HEAVY",
+											   &start_iter, &end_iter);
+						else gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_ULTRAHEAVY",
+											&start_iter, &end_iter);
+						break;
+					default:
+						break;
+					}
+				}
+				go_slist_free_custom (attr, (GFreeFunc)pango_attribute_destroy);
+			}
+		} while (pango_attr_iterator_next (iter));
+		pango_attr_iterator_destroy (iter);
+		pango_attr_list_unref (our_markup);
+	}
+
+/* For other styles (that are not at true/false type styles) we use unnamed styles */
+
+	copied_markup = pango_attr_list_copy (markup);
+	our_markup = pango_attr_list_filter (copied_markup,
+					     go_load_pango_attributes_into_buffer_filter,
+					     NULL);
+	pango_attr_list_unref (copied_markup);
+	if (our_markup != NULL) {
+		iter = pango_attr_list_get_iterator (our_markup);
+
+		do {
+			GSList *attr = pango_attr_iterator_get_attrs (iter);
+			if (attr != NULL) {
+				char *string;
+				GSList *ptr;
+				gint start, end;
+				GtkTextIter start_iter, end_iter;
+				GtkTextTag *tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
+				for (ptr = attr; ptr != NULL; ptr = ptr->next) {
+					PangoAttribute *attribute = ptr->data;
+					switch (attribute->klass->type) {
+					case PANGO_ATTR_FOREGROUND:
+						string = pango_color_to_string
+							(&((PangoAttrColor *)attribute)->color);
+						g_object_set (G_OBJECT (tag),
+							      "foreground", string,
+							      "foreground-set", TRUE,
+							      NULL);
+						g_free (string);
+						break;
+					case PANGO_ATTR_UNDERLINE:
+						g_object_set (G_OBJECT (tag),
+							      "underline",
+							      ((PangoAttrInt *)attribute)->value,
+							      "underline-set", TRUE,
+							      NULL);
+						break;
+					case PANGO_ATTR_RISE:
+						g_object_set (G_OBJECT (tag),
+							      "rise",
+							      ((PangoAttrInt *)attribute)->value,
+							      "rise-set", TRUE,
+							      NULL);
+						break;
+					default:
+						break;
+					}
+				}
+				pango_attr_iterator_range (iter, &start, &end);
+				start = go_load_pango_byte_to_char (str, start);
+				end = go_load_pango_byte_to_char (str, end);
+				gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
+				gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);
+				gtk_text_buffer_apply_tag (buffer, tag, &start_iter, &end_iter);
+				go_slist_free_custom (attr, (GFreeFunc)pango_attribute_destroy);
+			}
+		} while (pango_attr_iterator_next (iter));
+		pango_attr_iterator_destroy (iter);
+		pango_attr_list_unref (our_markup);
+	}
+}
diff --git a/goffice/utils/go-pango-extras.h b/goffice/utils/go-pango-extras.h
index 18fd95a..33c7339 100644
--- a/goffice/utils/go-pango-extras.h
+++ b/goffice/utils/go-pango-extras.h
@@ -2,6 +2,7 @@
 #define GO_PANGO_EXTRAS_H
 
 #include <pango/pango.h>
+#include <gtk/gtk.h>
 
 G_BEGIN_DECLS
 
@@ -12,6 +13,11 @@ void go_pango_attr_list_unset (PangoAttrList  *list,
 			       PangoAttrType type);
 gboolean go_pango_attr_list_is_empty (const PangoAttrList *attrs);
 
+void go_load_pango_attributes_into_buffer (PangoAttrList *markup, 
+					   GtkTextBuffer *buffer, 
+					   gchar const *str);
+void go_create_std_tags_for_buffer (GtkTextBuffer *buffer);
+
 G_END_DECLS
 
 #endif /* GO_PANGO_EXTRAS_H */
diff --git a/plugins/plot_distrib/gog-histogram.c b/plugins/plot_distrib/gog-histogram.c
index 9a38c82..f63b9ff 100644
--- a/plugins/plot_distrib/gog-histogram.c
+++ b/plugins/plot_distrib/gog-histogram.c
@@ -760,35 +760,35 @@ gog_histogram_plot_view_render (GogView *view, GogViewAllocation const *bbox)
 					alloc.x = area->x + 2; /* FIXME: replace 2 by something configurable */
 					alloc.y = area->y + 2;
 					gog_renderer_draw_text (view->renderer, text, &alloc,
-							        GTK_ANCHOR_NORTH_WEST, FALSE);
+							        GTK_ANCHOR_NORTH_WEST, NULL, FALSE);
 					text = (text2)? text2: _("Second values");
 					alloc.y = area->y + area->h - 2;
 					gog_renderer_draw_text (view->renderer, text, &alloc,
-							        GTK_ANCHOR_SOUTH_WEST, FALSE);
+							        GTK_ANCHOR_SOUTH_WEST, NULL, FALSE);
 				} else {
 					alloc.x = area->x + area->w - 2; /* FIXME: replace 2 by something configurable */
 					alloc.y = area->y + area->h - 2;
 					gog_renderer_draw_text (view->renderer, text, &alloc,
-							        GTK_ANCHOR_SOUTH_EAST, FALSE);
+							        GTK_ANCHOR_SOUTH_EAST, NULL, FALSE);
 					text = (text2)? text2: _("Second values");
 					alloc.x = area->x + 2;
 					gog_renderer_draw_text (view->renderer, text, &alloc,
-							        GTK_ANCHOR_SOUTH_WEST, FALSE);
+							        GTK_ANCHOR_SOUTH_WEST, NULL, FALSE);
 				}
 			} else {
 				alloc.x = area->x + area->w - 2; /* FIXME: replace 2 by something configurable */
 				alloc.y = area->y + 2;
 				gog_renderer_draw_text (view->renderer, text, &alloc,
-					                GTK_ANCHOR_NORTH_EAST, FALSE);
+					                GTK_ANCHOR_NORTH_EAST, NULL, FALSE);
 				text = (text2)? text2: _("Second values");
 				if (model->vertical) {
 					alloc.y = area->y + area->h - 2;
 					gog_renderer_draw_text (view->renderer, text, &alloc,
-							        GTK_ANCHOR_SOUTH_EAST, FALSE);
+							        GTK_ANCHOR_SOUTH_EAST, NULL, FALSE);
 				} else {
 					alloc.x = area->x + 2;
 					gog_renderer_draw_text (view->renderer, text, &alloc,
-							        GTK_ANCHOR_NORTH_WEST, FALSE);
+							        GTK_ANCHOR_NORTH_WEST, NULL, FALSE);
 				}
 			}
 			g_free (text1);
