+size_t
+table_collect_footnotes (const struct table_item *item,
+ const struct footnote ***footnotesp)
+{
+ const struct footnote **footnotes = NULL;
+ size_t allocated = 0;
+ size_t n = 0;
+
+ struct table *t = item->table;
+ for (int y = 0; y < table_nr (t); y++)
+ {
+ struct table_cell cell;
+ for (int x = 0; x < table_nc (t); x = cell.d[TABLE_HORZ][1])
+ {
+ table_get_cell (t, x, y, &cell);
+
+ if (x == cell.d[TABLE_HORZ][0] && y == cell.d[TABLE_VERT][0])
+ footnotes = add_footnotes (cell.footnotes, cell.n_footnotes,
+ footnotes, &allocated, &n);
+ }
+ }
+
+ const struct table_item_text *title = table_item_get_title (item);
+ if (title)
+ footnotes = add_footnotes (title->footnotes, title->n_footnotes,
+ footnotes, &allocated, &n);
+
+ const struct table_item_layers *layers = table_item_get_layers (item);
+ if (layers)
+ {
+ for (size_t i = 0; i < layers->n_layers; i++)
+ footnotes = add_footnotes (layers->layers[i].footnotes,
+ layers->layers[i].n_footnotes,
+ footnotes, &allocated, &n);
+ }
+
+ const struct table_item_text *caption = table_item_get_caption (item);
+ if (caption)
+ footnotes = add_footnotes (caption->footnotes, caption->n_footnotes,
+ footnotes, &allocated, &n);
+
+ size_t n_nonnull = 0;
+ for (size_t i = 0; i < n; i++)
+ if (footnotes[i])
+ footnotes[n_nonnull++] = footnotes[i];
+
+ *footnotesp = footnotes;
+ return n_nonnull;
+}
+\f
+/* Returns a table that contains a single cell, whose contents are the
+ left-aligned TEXT. */
+struct table *
+table_from_string (const char *text)