+struct text_item *
+text_item_unshare (struct text_item *old)
+{
+ assert (old->output_item.ref_cnt > 0);
+ if (!text_item_is_shared (old))
+ return old;
+ text_item_unref (old);
+
+ struct text_item *new = xmalloc (sizeof *new);
+ *new = (struct text_item) {
+ .output_item = OUTPUT_ITEM_CLONE_INITIALIZER (&old->output_item),
+ .text = xstrdup (old->text),
+ .type = old->type,
+ .bold = old->bold,
+ .italic = old->italic,
+ .underline = old->underline,
+ .markup = old->markup,
+ .typeface = old->typeface ? xstrdup (old->typeface) : NULL,
+ .size = old->size
+ };
+ return new;
+}
+
+/* Attempts to append the text in SRC to DST. If successful, returns true,
+ otherwise false.
+
+ Only TEXT_ITEM_SYNTAX and TEXT_ITEM_LOG items can be combined, and not with
+ each other.
+
+ DST must not be shared. */
+bool
+text_item_append (struct text_item *dst, const struct text_item *src)
+{
+ assert (!text_item_is_shared (dst));
+ if (dst->type != src->type
+ || (dst->type != TEXT_ITEM_SYNTAX && dst->type != TEXT_ITEM_LOG)
+ || strcmp (output_item_get_label (&dst->output_item),
+ output_item_get_label (&src->output_item))
+ || dst->bold != src->bold
+ || dst->italic != src->italic
+ || dst->underline != src->underline
+ || dst->markup
+ || src->markup
+ || strcmp (dst->typeface ? dst->typeface : "",
+ src->typeface ? src->typeface : "")
+ || dst->size != src->size)
+ return false;
+ else
+ {
+ char *new_text = xasprintf ("%s\n%s", dst->text, src->text);
+ free (dst->text);
+ dst->text = new_text;
+ return true;
+ }
+}
+