+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,
+ };
+ font_style_copy (NULL, &new->style, &old->style);
+ 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))
+ || !font_style_equal (&dst->style, &src->style)
+ || dst->style.markup)
+ return false;
+ else
+ {
+ char *new_text = xasprintf ("%s\n%s", dst->text, src->text);
+ free (dst->text);
+ dst->text = new_text;
+ return true;
+ }
+}
+
+static const struct pivot_table_look *
+text_item_table_look (void)
+{
+ static struct pivot_table_look *look;
+ if (!look)
+ {
+ look = pivot_table_look_new_builtin_default ();
+
+ for (int a = 0; a < PIVOT_N_AREAS; a++)
+ memset (look->areas[a].cell_style.margin, 0,
+ sizeof look->areas[a].cell_style.margin);
+ for (int b = 0; b < PIVOT_N_BORDERS; b++)
+ look->borders[b].stroke = TABLE_STROKE_NONE;
+ }
+ return look;
+}
+