-
-struct footnote *
-footnote_clone (const struct footnote *old)
-{
- struct footnote *new = xmalloc (sizeof *new);
- *new = (struct footnote) {
- .idx = old->idx,
- .content = old->content ? xstrdup (old->content) : NULL,
- .marker = old->marker ? xstrdup (old->marker) : NULL,
- .style = old->style ? table_area_style_clone (NULL, old->style) : NULL,
- };
- return new;
-}
-
-void
-footnote_destroy (struct footnote *f)
-{
- if (f)
- {
- free (f->content);
- free (f->marker);
- if (f->style)
- {
- table_area_style_uninit (f->style);
- free (f->style);
- }
- free (f);
- }
-}
-
-struct table_cell *
-table_cell_clone (const struct table_cell *old)
-{
- struct table_cell *new = xmalloc (sizeof *new);
- *new = *old;
- new->text = xstrdup (new->text);
-
- if (old->n_subscripts)
- {
- new->subscripts = xnmalloc (old->n_subscripts, sizeof *new->subscripts);
- for (size_t i = 0; i < old->n_subscripts; i++)
- new->subscripts[i] = xstrdup (old->subscripts[i]);
- }
- else
- new->subscripts = NULL;
-
- if (old->n_footnotes)
- {
- new->footnotes = xnmalloc (old->n_footnotes, sizeof *new->footnotes);
- for (size_t i = 0; i < old->n_footnotes; i++)
- new->footnotes[i] = footnote_clone (old->footnotes[i]);
- }
- else
- new->footnotes = NULL;
-
- if (old->style)
- new->style = table_area_style_clone (NULL, old->style);
-
- return new;
-}
-
-void
-table_cell_destroy (struct table_cell *cell)
-{
- if (!cell)
- return;
-
- free (cell->text);
- for (size_t i = 0; i < cell->n_subscripts; i++)
- free (cell->subscripts[i]);
- free (cell->subscripts);
- for (size_t i = 0; i < cell->n_footnotes; i++)
- footnote_destroy (cell->footnotes[i]);
- free (cell->footnotes);
- if (cell->style)
- {
- table_area_style_uninit (cell->style);
- free (cell->style);
- }
- free (cell);
-}
-
-void
-table_cell_format_footnote_markers (const struct table_cell *cell,
- struct string *s)
-{
- for (size_t i = 0; i < cell->n_footnotes; i++)
- {
- if (i)
- ds_put_byte (s, ',');
- ds_put_cstr (s, cell->footnotes[i]->marker);
- }
-}
-
-static struct footnote **
-add_footnotes (struct footnote **refs, size_t n_refs,
- struct footnote **footnotes, size_t *allocated, size_t *n)
-{
- for (size_t i = 0; i < n_refs; i++)
- {
- struct footnote *f = refs[i];
- if (f->idx >= *allocated)
- {
- size_t new_allocated = (f->idx + 1) * 2;
- footnotes = xrealloc (footnotes, new_allocated * sizeof *footnotes);
- while (*allocated < new_allocated)
- footnotes[(*allocated)++] = NULL;
- }
- footnotes[f->idx] = f;
- if (f->idx >= *n)
- *n = f->idx + 1;
- }
- return footnotes;
-}
-
-size_t
-table_collect_footnotes (const struct table_item *item,
- struct footnote ***footnotesp)
-{
- struct footnote **footnotes = NULL;
- size_t allocated = 0;
- size_t n = 0;
-
- struct table *t = item->table;
- for (int y = 0; y < t->n[V]; y++)
- {
- struct table_cell cell;
- for (int x = 0; x < t->n[H]; 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_cell *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_cell *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;
-}