for (size_t i = 0; i < cell->n_subscripts; i++)
ds_put_format (&s, "%c%s", i ? ',' : '_', cell->subscripts[i]);
for (size_t i = 0; i < cell->n_footnotes; i++)
- ds_put_format (&s, "[%s]", cell->footnotes[i]->marker);
+ {
+ ds_put_byte (&s, '[');
+ pivot_value_format (cell->footnotes[i]->marker,
+ SETTINGS_VALUE_SHOW_DEFAULT,
+ SETTINGS_VALUE_SHOW_DEFAULT, &s);
+ ds_put_byte (&s, ']');
+ }
return ds_steal_cstr (&s);
}
{
if (i)
ds_put_byte (&tmp, ',');
- ds_put_cstr (&tmp, cell->footnotes[i]->marker);
+
+ pivot_value_format (cell->footnotes[i]->marker,
+ SETTINGS_VALUE_SHOW_DEFAULT,
+ SETTINGS_VALUE_SHOW_DEFAULT, &tmp);
}
/* Allow footnote markers to occupy the right margin. That way, numbers
#include "output/message-item.h"
#include "output/page-eject-item.h"
#include "output/pivot-output.h"
+#include "output/pivot-table.h"
#include "output/table-item.h"
#include "output/table-provider.h"
}
}
-static void
-csv_format_footnotes (struct footnote **f, size_t n, struct string *s)
-{
- for (size_t i = 0; i < n; i++)
- ds_put_format (s, "[%s]", f[i]->marker);
-}
-
static void
csv_output_table_cell (struct csv_driver *csv, const struct table_cell *cell,
const char *leader)
for (size_t i = 0; i < cell->n_subscripts; i++)
ds_put_format (&s, "%c%s",
i ? ',' : '_', cell->subscripts[i]);
- csv_format_footnotes (cell->footnotes, cell->n_footnotes, &s);
+ for (size_t i = 0; i < cell->n_footnotes; i++)
+ {
+ ds_put_byte (&s, '[');
+ pivot_value_format (cell->footnotes[i]->marker,
+ SETTINGS_VALUE_SHOW_DEFAULT,
+ SETTINGS_VALUE_SHOW_DEFAULT, &s);
+ ds_put_byte (&s, ']');
+ }
csv_output_field (csv, ds_cstr (&s));
ds_destroy (&s);
}
}
-static void
-html_put_footnote_markers (struct html_driver *html,
- struct footnote **footnotes,
- size_t n_footnotes)
-{
- if (n_footnotes > 0)
- {
- fputs ("<sup>", html->file);
- for (size_t i = 0; i < n_footnotes; i++)
- {
- const struct footnote *f = footnotes[i];
-
- if (i > 0)
- putc (',', html->file);
- escape_string (html->file, f->marker, " ", "<br>");
- }
- fputs ("</sup>", html->file);
- }
-}
-
static void
html_put_table_cell_text (struct html_driver *html,
const struct table_cell *cell)
}
fputs ("</sub>", html->file);
}
- html_put_footnote_markers (html, cell->footnotes, cell->n_footnotes);
+ if (cell->n_footnotes > 0)
+ {
+ fputs ("<sup>", html->file);
+ for (size_t i = 0; i < cell->n_footnotes; i++)
+ {
+ if (i > 0)
+ putc (',', html->file);
+
+ char *marker = pivot_value_to_string (cell->footnotes[i]->marker,
+ SETTINGS_VALUE_SHOW_DEFAULT,
+ SETTINGS_VALUE_SHOW_DEFAULT);
+ escape_string (html->file, marker, " ", "<br>");
+ free (marker);
+ }
+ fputs ("</sup>", html->file);
+ }
}
static void
fputs ("</tr>\n", html->file);
}
- for (size_t y = 0; y < footnotes->n[V]; y++)
- {
- fputs ("<tr>\n", html->file);
+ if (footnotes)
+ for (size_t y = 0; y < footnotes->n[V]; y++)
+ {
+ fputs ("<tr>\n", html->file);
- struct table_cell cell;
- table_get_cell (footnotes, 0, y, &cell);
- cell.d[H][1] = body->n[H];
- html_put_table_cell (html, &cell, "td", NULL);
+ struct table_cell cell;
+ table_get_cell (footnotes, 0, y, &cell);
+ cell.d[H][1] = body->n[H];
+ html_put_table_cell (html, &cell, "td", NULL);
- fputs ("</tr>\n", html->file);
- }
+ fputs ("</tr>\n", html->file);
+ }
fputs ("</tfoot>\n", html->file);
}
xmlTextWriterEndElement (w); /* style:style */
}
+
{
xmlTextWriterStartElement (w, _xml ("style:style"));
xmlTextWriterWriteAttribute (w, _xml ("style:name"),
xmlTextWriterEndElement (w); /* style:style */
}
+ {
+ xmlTextWriterStartElement (w, _xml ("style:style"));
+ xmlTextWriterWriteAttribute (w, _xml ("style:name"), _xml ("superscript"));
+ xmlTextWriterWriteAttribute (w, _xml ("style:family"), _xml ("text"));
+
+ xmlTextWriterStartElement (w, _xml ("style:text-properties"));
+ xmlTextWriterWriteAttribute (w, _xml ("style:text-position"),
+ _xml ("super 58%"));
+ xmlTextWriterEndElement (w); /* style:text-properties */
+
+ xmlTextWriterEndElement (w); /* style:style */
+ }
xmlTextWriterEndElement (w); /* office:styles */
xmlTextWriterEndElement (w); /* office:document-styles */
}
static void
-write_footnote (struct odt_driver *odt, const struct footnote *f)
+write_footnotes (struct odt_driver *odt, struct pivot_footnote **footnotes,
+ size_t n_footnotes)
{
- xmlTextWriterStartElement (odt->content_wtr, _xml("text:note"));
- xmlTextWriterWriteAttribute (odt->content_wtr, _xml("text:note-class"),
- _xml("footnote"));
-
- xmlTextWriterStartElement (odt->content_wtr, _xml("text:note-citation"));
- if (strlen (f->marker) > 1)
- xmlTextWriterWriteFormatAttribute (odt->content_wtr, _xml("text:label"),
- "(%s)", f->marker);
- else
- xmlTextWriterWriteAttribute (odt->content_wtr, _xml("text:label"),
- _xml(f->marker));
- xmlTextWriterEndElement (odt->content_wtr);
-
- xmlTextWriterStartElement (odt->content_wtr, _xml("text:note-body"));
- xmlTextWriterStartElement (odt->content_wtr, _xml("text:p"));
- write_xml_with_line_breaks (odt, f->content);
- xmlTextWriterEndElement (odt->content_wtr);
- xmlTextWriterEndElement (odt->content_wtr);
-
- xmlTextWriterEndElement (odt->content_wtr);
+ for (size_t i = 0; i < n_footnotes; i++)
+ {
+ xmlTextWriterStartElement (odt->content_wtr, _xml("text:span"));
+ xmlTextWriterWriteAttribute (odt->content_wtr, _xml("text:style-name"),
+ _xml("superscript"));
+ char *s = pivot_value_to_string (footnotes[i]->marker,
+ SETTINGS_VALUE_SHOW_DEFAULT,
+ SETTINGS_VALUE_SHOW_DEFAULT);
+ write_xml_with_line_breaks (odt, s);
+ free (s);
+ xmlTextWriterEndElement (odt->content_wtr);
+ }
}
static void
xmlTextWriterWriteFormatAttribute (odt->content_wtr,
_xml("text:outline-level"), "%d", 2);
xmlTextWriterWriteString (odt->content_wtr, _xml (cell->text));
- for (size_t i = 0; i < cell->n_footnotes; i++)
- write_footnote (odt, cell->footnotes[i]);
+ write_footnotes (odt, cell->footnotes, cell->n_footnotes);
xmlTextWriterEndElement (odt->content_wtr);
}
else
write_xml_with_line_breaks (odt, cell.text);
- for (int i = 0; i < cell.n_footnotes; i++)
- write_footnote (odt, cell.footnotes[i]);
+ write_footnotes (odt, cell.footnotes, cell.n_footnotes);
xmlTextWriterEndElement (odt->content_wtr); /* text:p */
xmlTextWriterEndElement (odt->content_wtr); /* table:table-cell */
else if (!indexes)
{
size_t size = layer_axis->n_dimensions * sizeof *pt->current_layer;
- return xmemdup (pt->current_layer, MAX (size, 1));
+ return size ? xmemdup (pt->current_layer, size) : xmalloc (1);
}
else
{
static void
fill_cell (struct table *t, int x1, int y1, int x2, int y2,
const struct table_area_style *style, int style_idx,
- const struct pivot_value *value, struct footnote **footnotes,
+ const struct pivot_value *value,
enum settings_value_show show_values,
enum settings_value_show show_variables,
bool rotate_label)
value->font_style,
rotate_label));
- for (size_t i = 0; i < value->n_footnotes; i++)
- {
- struct footnote *f = footnotes[value->footnotes[i]->idx];
- if (f)
- table_add_footnote (t, x1, y1, f);
- }
+ table_add_footnotes (t, x1, y1,
+ (struct pivot_footnote **) value->footnotes,
+ value->n_footnotes);
if (value->n_subscripts)
table_add_subscripts (t, x1, y1,
const struct table_area_style *label_style,
int label_style_idx,
const struct table_area_style *corner_style,
- struct footnote **footnotes,
enum settings_value_show show_values,
enum settings_value_show show_variables,
bool rotate_inner_labels, bool rotate_outer_labels)
bool rotate = ((rotate_inner_labels && is_inner_row)
|| (rotate_outer_labels && is_outer_row));
fill_cell (t, bb[H][0], bb[V][0], bb[H][1], bb[V][1],
- label_style, label_style_idx, c->name, footnotes,
+ label_style, label_style_idx, c->name,
show_values, show_variables, rotate);
if (pivot_category_is_leaf (c) && x2 + 1 <= n_columns)
bb[b][0] = bottom_row - d->label_depth + 1;
bb[b][1] = bottom_row;
fill_cell (t, bb[H][0], bb[V][0], bb[H][1], bb[V][1],
- corner_style, PIVOT_AREA_CORNER, d->root->name, footnotes,
+ corner_style, PIVOT_AREA_CORNER, d->root->name,
show_values, show_variables, false);
}
{
struct table *table = table_create (nr, nc, 0, 0, 0, 0);
table->styles[style_idx] = table_area_style_override (
- t->container, &pt->look->areas[style_idx], NULL, NULL, false);
+ table->container, &pt->look->areas[style_idx], NULL, NULL, false);
return table;
}
-static struct footnote **
-add_footnotes (struct footnote **refs, size_t n_refs,
- struct footnote **footnotes, size_t *allocated, size_t *n)
+static void
+add_references (const struct pivot_table *pt, const struct table *table,
+ bool *refs, size_t *n_refs)
{
- 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;
+ if (!table)
+ return;
+
+ for (int y = 0; y < table->n[V]; y++)
+ for (int x = 0; x < table->n[H]; )
+ {
+ struct table_cell cell;
+ table_get_cell (table, x, y, &cell);
+
+ if (x == cell.d[H][0] && y == cell.d[V][0])
+ {
+ for (size_t i = 0; i < cell.n_footnotes; i++)
+ {
+ const struct pivot_footnote *f = cell.footnotes[i];
+ assert (f->idx < pt->n_footnotes);
+ assert (f == pt->footnotes[f->idx]);
+
+ if (!refs[f->idx])
+ {
+ refs[f->idx] = true;
+ (*n_refs)++;
+ }
+ }
+ }
+
+ x = cell.d[TABLE_HORZ][1];
+ }
}
-size_t
-table_collect_footnotes (const struct table *
- struct footnote ***footnotesp)
+static struct pivot_footnote **
+collect_footnotes (const struct pivot_table *pt,
+ const struct table *title,
+ const struct table *layers,
+ const struct table *body,
+ const struct table *caption,
+ size_t *n_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++)
+ if (!pt->n_footnotes)
{
- 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);
- }
+ *n_footnotesp = 0;
+ return NULL;
}
- 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);
- }
+ bool *refs = xzalloc (pt->n_footnotes);
+ size_t n_refs = 0;
+ add_references (pt, title, refs, &n_refs);
+ add_references (pt, layers, refs, &n_refs);
+ add_references (pt, body, refs, &n_refs);
+ add_references (pt, caption, refs, &n_refs);
- const struct table_cell *caption = table_item_get_caption (item);
- if (caption)
- footnotes = add_footnotes (caption->footnotes, caption->n_footnotes,
- footnotes, &allocated, &n);
+ struct pivot_footnote **footnotes = xnmalloc (n_refs, sizeof *footnotes);
+ size_t n_footnotes = 0;
+ for (size_t i = 0; i < pt->n_footnotes; i++)
+ if (refs[i])
+ footnotes[n_footnotes++] = pt->footnotes[i];
+ assert (n_footnotes == n_refs);
- size_t n_nonnull = 0;
- for (size_t i = 0; i < n; i++)
- if (footnotes[i])
- footnotes[n_nonnull++] = footnotes[i];
+ free (refs);
- *footnotesp = footnotes;
- return n_nonnull;
+ *n_footnotesp = n_footnotes;
+ return footnotes;
}
void
struct table **bodyp,
struct table **captionp,
struct table **footnotesp,
- struct footnote ***fp, size_t *nfp)
+ struct pivot_footnote ***fp, size_t *nfp)
{
const size_t *pindexes[PIVOT_N_AXES]
= { [PIVOT_AXIS_LAYER] = layer_indexes };
*body->rule_colors[i] = in->color;
}
- struct footnote **footnotes = XCALLOC (pt->n_footnotes, struct footnote *);
- for (size_t i = 0; i < pt->n_footnotes; i++)
- {
- const struct pivot_footnote *pf = pt->footnotes[i];
-
- if (!pf->show)
- continue;
-
- char *content = pivot_value_to_string (pf->content, pt->show_values,
- pt->show_variables);
- char *marker = pivot_value_to_string (pf->marker, pt->show_values,
- pt->show_variables);
- footnotes[i] = table_create_footnote (
- body, i, content, marker,
- table_area_style_override (body->container,
- &pt->look->areas[PIVOT_AREA_FOOTER],
- pf->content->cell_style,
- pf->content->font_style,
- false));
- free (marker);
- free (content);
- }
-
compose_headings (body,
&pt->axes[PIVOT_AXIS_COLUMN], H, &pt->axes[PIVOT_AXIS_ROW],
pt->look->borders,
column_enumeration, data[H],
&pt->look->areas[PIVOT_AREA_COLUMN_LABELS],
PIVOT_AREA_COLUMN_LABELS,
- &pt->look->areas[PIVOT_AREA_CORNER], footnotes,
+ &pt->look->areas[PIVOT_AREA_CORNER],
pt->show_values, pt->show_variables,
pt->rotate_outer_row_labels, false);
row_enumeration, data[V],
&pt->look->areas[PIVOT_AREA_ROW_LABELS],
PIVOT_AREA_ROW_LABELS,
- &pt->look->areas[PIVOT_AREA_CORNER], footnotes,
+ &pt->look->areas[PIVOT_AREA_CORNER],
pt->show_values, pt->show_variables,
false, pt->rotate_inner_column_labels);
x + stub[H], y + stub[V],
x + stub[H], y + stub[V],
&pt->look->areas[PIVOT_AREA_DATA], PIVOT_AREA_DATA,
- value, footnotes,
- pt->show_values, pt->show_variables, false);
+ value, pt->show_values, pt->show_variables, false);
x++;
}
&& stub[H] && stub[V])
fill_cell (body, 0, 0, stub[H] - 1, stub[V] - 1,
&pt->look->areas[PIVOT_AREA_CORNER], PIVOT_AREA_CORNER,
- pt->corner_text, footnotes,
- pt->show_values, pt->show_variables, false);
+ pt->corner_text, pt->show_values, pt->show_variables, false);
if (body->n[H] && body->n[V])
{
if (pt->title && titlep)
{
title = create_aux_table (pt, 1, 1, PIVOT_AREA_TITLE);
- fill_cell (title, 0, 0, 1, 1,
+ fill_cell (title, 0, 0, 0, 0,
&pt->look->areas[PIVOT_AREA_TITLE], PIVOT_AREA_TITLE,
- pt->title, footnotes,
- pt->show_values, pt->show_variables, false);
+ pt->title, pt->show_values, pt->show_variables, false);
}
else
title = NULL;
/* XXX This puts in the layer values, but not the variable names. */
const struct pivot_value *name
= d->data_leaves[layer_indexes[i]]->name;
- fill_cell (layers, 0, y, 1, y + 1,
+ fill_cell (layers, 0, y, 0, y,
&pt->look->areas[PIVOT_AREA_LAYERS], PIVOT_AREA_LAYERS,
- name, footnotes,
- pt->show_values, pt->show_variables, false);
+ name, pt->show_values, pt->show_variables, false);
y++;
}
}
if (pt->caption && captionp)
{
caption = create_aux_table (pt, 1, 1, PIVOT_AREA_CAPTION);
- fill_cell (caption, 0, 0, 1, 1,
+ fill_cell (caption, 0, 0, 0, 0,
&pt->look->areas[PIVOT_AREA_CAPTION], PIVOT_AREA_CAPTION,
- pt->caption, footnotes,
- pt->show_values, pt->show_variables, false);
+ pt->caption, pt->show_values, pt->show_variables, false);
}
else
caption = NULL;
- free (footnotes);
+ /* Footnotes. */
+ size_t nf;
+ struct pivot_footnote **f = collect_footnotes (pt, title, layers, body,
+ caption, &nf);
+ struct table *footnotes;
+ if (nf && footnotesp)
+ {
+ footnotes = create_aux_table (pt, 1, nf, PIVOT_AREA_FOOTER);
+ for (size_t i = 0; i < nf; i++)
+ {
+ struct string s = DS_EMPTY_INITIALIZER;
+ pivot_value_format (f[i]->marker, pt->show_values,
+ pt->show_variables, &s);
+ ds_put_cstr (&s, ". ");
+ pivot_value_format (f[i]->content, pt->show_values,
+ pt->show_variables, &s);
+
+ struct pivot_value *value = pivot_value_new_user_text_nocopy (
+ ds_steal_cstr (&s));
+
+ fill_cell (layers, 0, i, 0, i,
+ &pt->look->areas[PIVOT_AREA_FOOTER], PIVOT_AREA_FOOTER,
+ value, pt->show_values, pt->show_variables, false);
+ }
+ }
+ else
+ footnotes = NULL;
+
+ *titlep = title;
+ if (layersp)
+ *layersp = layers;
*bodyp = body;
+ if (captionp)
+ *captionp = caption;
+ if (footnotesp)
+ *footnotesp = footnotes;
+ if (fp)
+ {
+ *fp = f;
+ *nfp = nf;
+ }
+ else
+ free (f);
}
void
#include <stdbool.h>
#include <stddef.h>
-struct footnote;
+struct pivot_footnote;
struct pivot_table;
struct table;
struct table **bodyp,
struct table **captionp,
struct table **footnotesp,
- struct footnote ***fp, size_t *nfp);
+ struct pivot_footnote ***fp, size_t *nfp);
#endif /* output/pivot-output.h */
struct render_break y_break;
};
-static const struct render_page *
+static void
render_pager_add_table (struct render_pager *p, struct table *table,
int min_width)
{
- struct render_page *page = render_page_create (p->params, table, min_width);
- p->pages[p->n_pages++] = page;
- return page;
+ if (table)
+ p->pages[p->n_pages++] = render_page_create (p->params, table, min_width);
}
static void
}
void table_item_submit (struct table_item *);
-\f
+
#endif /* output/table-item.h */
enum table_halign table_halign_interpret (enum table_halign, bool numeric);
-struct footnote
- {
- //size_t idx;
- char *content;
- char *marker;
- struct table_area_style *style;
- };
-
-struct footnote *footnote_clone (const struct footnote *);
-void footnote_destroy (struct footnote *);
-
/* A cell in a table. */
struct table_cell
{
char *text; /* A paragraph of text. */
char **subscripts;
size_t n_subscripts;
- struct footnote **footnotes;
+ struct pivot_footnote **footnotes;
size_t n_footnotes;
struct table_area_style *style;
};
struct table_cell *table_cell_clone (const struct table_cell *);
void table_cell_destroy (struct table_cell *);
-void table_cell_format_footnote_markers (const struct table_cell *,
- struct string *);
-
/* Returns the number of columns that CELL spans. This is 1 for an ordinary
cell and greater than one for a cell that joins multiple columns. */
static inline int
void table_get_cell (const struct table *, int x, int y, struct table_cell *);
int table_get_rule (const struct table *, enum table_axis, int x, int y,
struct cell_color *);
-size_t table_collect_footnotes (const struct table_item *, struct footnote ***);
#endif /* output/table-provider.h */
free (style);
}
}
-
-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);
- }
-}
\f
const char *
table_halign_to_string (enum table_halign halign)
cell->subscripts[i] = pool_strdup (table->container, subscripts[i]);
}
-/* Create a footnote in TABLE with MARKER (e.g. "a") as its marker and CONTENT
- as its content. The footnote will be styled as STYLE, which is mandatory.
- IDX must uniquely identify the footnote within TABLE.
-
- Returns the new footnote. The return value is the only way to get to the
- footnote later, so it is important for the caller to remember it. */
-struct footnote *
-table_create_footnote (struct table *table, size_t idx, const char *content,
- const char *marker, struct table_area_style *style)
-{
- assert (style);
-
- struct footnote *f = pool_alloc (table->container, sizeof *f);
- f->idx = idx;
- f->content = pool_strdup (table->container, content);
- f->marker = pool_strdup (table->container, marker);
- f->style = style;
- return f;
-}
-
-/* Attaches a reference to footnote F to the cell at column X, row Y in
- TABLE. */
+/* Attaches a reference to the NF footnotes at F to the cell at column X, row Y
+ in TABLE. */
void
-table_add_footnote (struct table *table, int x, int y, struct footnote *f)
+table_add_footnotes (struct table *table, int x, int y,
+ struct pivot_footnote **f, size_t nf)
{
- assert (f->style);
-
struct table_cell *cell = get_joined_cell (table, x, y);
cell->footnotes = pool_realloc (
table->container, cell->footnotes,
- (cell->n_footnotes + 1) * sizeof *cell->footnotes);
+ (cell->n_footnotes + nf) * sizeof *cell->footnotes);
- cell->footnotes[cell->n_footnotes++] = f;
+ for (size_t i = 0; i < nf; i++)
+ cell->footnotes[cell->n_footnotes++] = f[i];
}
/* Overrides the style for column X, row Y in TABLE with STYLE.
struct casereader;
struct fmt_spec;
+struct pivot_footnote;
struct pool;
struct table_item;
struct variable;
void table_add_subscripts (struct table *, int x, int y,
char **subscripts, size_t n_subscripts);
-/* Footnotes.
-
- Use table_create_footnote() to create the footnotes themselves, then use
- table_add_footnote() to create a reference from a table cell to a footnote.
- There are two steps because a footnote may have multiple references. */
-struct footnote *table_create_footnote (struct table *, size_t idx,
- const char *content,
- const char *marker,
- struct table_area_style *);
-void table_add_footnote (struct table *, int x, int y, struct footnote *);
+void table_add_footnotes (struct table *, int x, int y,
+ struct pivot_footnote **f, size_t nf);
void table_add_style (struct table *, int x, int y, struct table_area_style *);
static void
tex_put_footnote_markers (struct tex_driver *tex,
- struct footnote **footnotes,
+ struct pivot_footnote **footnotes,
size_t n_footnotes)
{
if (n_footnotes > 0)
shipout (&tex->token_list, "$^{");
for (size_t i = 0; i < n_footnotes; i++)
{
- const struct footnote *f = footnotes[i];
-
- tex_escape_string (tex, f->marker, true);
+ char *marker = pivot_value_to_string (footnotes[i]->marker,
+ SETTINGS_VALUE_SHOW_DEFAULT,
+ SETTINGS_VALUE_SHOW_DEFAULT);
+ tex_escape_string (tex, marker, true);
+ free (marker);
}
if (n_footnotes > 0)
shipout (&tex->token_list, "}$");
/* Tables are rendered in TeX with the \halign command.
This is described in the TeXbook Ch. 22 */
struct table *title, *layers, *body, *caption;
- struct footnote **footnotes;
+ struct pivot_footnote **footnotes;
size_t n_footnotes;
pivot_output (pt, layer_indexes, &title, &layers, &body,
&caption, NULL, &footnotes, &n_footnotes);
for (int i = 0; i < n_footnotes; ++i)
{
+ char *marker = pivot_value_to_string (footnotes[i]->marker,
+ SETTINGS_VALUE_SHOW_DEFAULT,
+ SETTINGS_VALUE_SHOW_DEFAULT);
+ char *content = pivot_value_to_string (footnotes[i]->content,
+ SETTINGS_VALUE_SHOW_DEFAULT,
+ SETTINGS_VALUE_SHOW_DEFAULT);
+
shipout (&tex->token_list, "$^{");
- tex_escape_string (tex, footnotes[i]->marker, false);
+ tex_escape_string (tex, marker, false);
shipout (&tex->token_list, "}$");
- tex_escape_string (tex, footnotes[i]->content, false);
+ tex_escape_string (tex, content, false);
+
+ free (content);
+ free (marker);
}
shipout (&tex->token_list, "}\n\\vskip 3ex\n\n");
}
}
+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;
+}
+
struct table_item *
text_item_to_table_item (struct text_item *text_item)
{
struct pivot_table *table = pivot_table_create__ (NULL, "Text");
- pivot_table_set_look (table, pivot_table_look_builtin_default ());
+ pivot_table_set_look (table, text_item_table_look ());
struct pivot_dimension *d = pivot_dimension_create (
table, PIVOT_AXIS_ROW, N_("Text"));