output: Break struct pivot_table_look out of struct pivot_table.
[pspp] / src / output / pivot-table.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2017-2018 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifndef OUTPUT_PIVOT_TABLE_H
18 #define OUTPUT_PIVOT_TABLE_H 1
19
20 #include <stdint.h>
21 #include <time.h>
22 #include "data/format.h"
23 #include "data/settings.h"
24 #include "libpspp/compiler.h"
25 #include "libpspp/hmap.h"
26 #include "output/table.h"
27
28 struct pivot_value;
29 struct variable;
30 union value;
31
32 /* Pivot tables.
33
34    Pivot tables are PSPP's primary form of output.  They are analogous to the
35    pivot tables you might be familiar with from spreadsheets and databases.
36    See https://en.wikipedia.org/wiki/Pivot_table for a brief introduction to
37    the overall concept of a pivot table.
38
39    In PSPP, the most important internal pieces of a pivot table are:
40
41    - Title.  Every pivot table has a title that is displayed above it.  It also
42      has an optional caption (displayed below it) and corner text (displayed in
43      the upper left corner).
44
45    - Dimensions.  A dimension consists of zero or more categories.  A category
46      has a label, such as "df" or "Asymp. Sig." or 123 or a variable name.  The
47      categories are the leaves of a tree whose non-leaf nodes form groups of
48      categories.  The tree always has a root group whose label is the name of
49      the dimension.
50
51    - Axes.  A table has three axes: column, row, and layer.  Each dimension is
52      assigned to an axis, and each axis has zero or more dimensions.  When an
53      axis has more than one dimension, they are ordered from innermost to
54      outermost.
55
56    - Data.  A table's data consists of zero or more cells.  Each cell maps from
57      a category for each dimension to a value, which is commonly a number but
58      could also be a variable name or an arbitrary text string.
59
60    Creating a pivot table usually consists of the following steps:
61
62    1. Create the table with pivot_table_create(), passing in the title.
63       It's commonly useful to set up a few options at this point:
64
65       - If empty rows or columns should not be displayed, set ->omit_empty to
66         true.
67
68       - Set the format to use for "count" values with
69         pivot_table_set_weight_var() or pivot_table_set_weight_format().
70
71    2. Create each dimension with pivot_dimension_create() and populate it with
72       categories and, possibly, with groups that contain the categories.  This
73       call also assigns the dimension to an axis.
74
75       In simple cases, only a call to pivot_dimension_create() is needed.
76       Other functions such as pivot_category_create_group() can be used for
77       hierarchies of categories.
78
79       Sometimes it's easier to create categories in tandem with inserting data,
80       for example by adding a category for a variable just before inserting the
81       first cell for that variable.  In that case, creating categories and
82       inserting data can be interleaved.
83
84    3. Insert data.  For each cell, supply the category indexes, which are
85       assigned starting from 0 in the order in which the categories were
86       created in step 2, and the value to go in the cell.  If the table has a
87       small, fixed number of dimensions, functions like, e.g.
88       pivot_table_put3() for 3 dimensions, can be used.  The general function
89       pivot_table_put() works for other cases.
90
91    4. Output the table for user consumption.  Use pivot_table_submit(). */
92 \f
93 /* Pivot table display styling. */
94
95 /* Areas of a pivot table for styling purposes. */
96 enum pivot_area
97   {
98     PIVOT_AREA_TITLE,
99     PIVOT_AREA_CAPTION,
100     PIVOT_AREA_FOOTER,          /* Footnotes. */
101     PIVOT_AREA_CORNER,          /* Top-left corner. */
102     PIVOT_AREA_COLUMN_LABELS,
103     PIVOT_AREA_ROW_LABELS,
104     PIVOT_AREA_DATA,
105     PIVOT_AREA_LAYERS,          /* Layer indication. */
106     PIVOT_N_AREAS
107   };
108
109 const char *pivot_area_to_string (enum pivot_area);
110 const struct table_area_style *pivot_area_get_default_style (enum pivot_area);
111
112 /* Table borders for styling purposes. */
113 enum pivot_border
114   {
115     PIVOT_BORDER_TITLE,
116
117     /* Outer frame. */
118     PIVOT_BORDER_OUTER_LEFT,
119     PIVOT_BORDER_OUTER_TOP,
120     PIVOT_BORDER_OUTER_RIGHT,
121     PIVOT_BORDER_OUTER_BOTTOM,
122
123     /* Inner frame. */
124     PIVOT_BORDER_INNER_LEFT,
125     PIVOT_BORDER_INNER_TOP,
126     PIVOT_BORDER_INNER_RIGHT,
127     PIVOT_BORDER_INNER_BOTTOM,
128
129     /* Data area. */
130     PIVOT_BORDER_DATA_LEFT,
131     PIVOT_BORDER_DATA_TOP,
132
133     /* Dimensions. */
134     PIVOT_BORDER_DIM_ROW_HORZ,
135     PIVOT_BORDER_DIM_ROW_VERT,
136     PIVOT_BORDER_DIM_COL_HORZ,
137     PIVOT_BORDER_DIM_COL_VERT,
138
139     /* Categories. */
140     PIVOT_BORDER_CAT_ROW_HORZ,
141     PIVOT_BORDER_CAT_ROW_VERT,
142     PIVOT_BORDER_CAT_COL_HORZ,
143     PIVOT_BORDER_CAT_COL_VERT,
144
145     PIVOT_N_BORDERS
146   };
147
148 const char *pivot_border_to_string (enum pivot_border);
149 void pivot_border_get_default_style (enum pivot_border,
150                                      struct table_border_style *);
151
152 /* Sizing for rows or columns of a rendered table.  The comments below talk
153    about columns and their widths but they apply equally to rows and their
154    heights. */
155 struct pivot_table_sizing
156   {
157     /* Specific column widths, in 1/96" units. */
158     int *widths;
159     size_t n_widths;
160
161     /* Specific page breaks: 0-based columns after which a page break must
162        occur, e.g. a value of 1 requests a break after the second column. */
163     size_t *breaks;
164     size_t n_breaks;
165
166     /* Keeps: columns to keep together on a page if possible. */
167     struct pivot_keep *keeps;
168     size_t n_keeps;
169   };
170
171 void pivot_table_sizing_uninit (struct pivot_table_sizing *);
172
173 /* A set of columns to keep together on a page if possible, e.g. ofs=1, n=10
174    requests keeping together the 2nd through 11th columns. */
175 struct pivot_keep
176   {
177     size_t ofs;                 /* 0-based first column. */
178     size_t n;                   /* Number of columns. */
179   };
180 \f
181 /* Axes. */
182
183 enum pivot_axis_type
184   {
185     PIVOT_AXIS_LAYER,
186     PIVOT_AXIS_ROW,
187     PIVOT_AXIS_COLUMN,
188
189     PIVOT_N_AXES
190   };
191
192 const char *pivot_axis_type_to_string (enum pivot_axis_type);
193
194 /* An axis within a pivot table. */
195 struct pivot_axis
196   {
197     /* dimensions[0] is the innermost dimension,
198        dimensions[1] is the next outer dimension,
199        ...
200        dimensions[n_dimensions - 1] is the outermost dimension. */
201     struct pivot_dimension **dimensions;
202     size_t n_dimensions;
203
204     /* The number of rows or columns along the axis,
205        that is, the product of dimension[*]->n_leaves.
206        It is 0 if any dimension has 0 leaves. */
207     size_t extent;
208
209     /* Sum of dimensions[*]->label_depth. */
210     size_t label_depth;
211   };
212
213 /* Successively assigns to INDEXES (which should be a "size_t *") each of the
214    combinations of the categories in AXIS's dimensions, in lexicographic order
215    with the innermost dimension iterating most quickly.
216
217    The value assigned to INDEXES is dynamically allocated.  If the client
218    breaks out of the loop prematurely, it needs to free it with free(). */
219 #define PIVOT_AXIS_FOR_EACH(INDEXES, AXIS)                              \
220   for ((INDEXES) = NULL;                                                \
221        ((INDEXES) = pivot_axis_iterator_next (INDEXES, AXIS)) != NULL;)
222 size_t *pivot_axis_iterator_next (size_t *indexes, const struct pivot_axis *);
223 \f
224 /* Dimensions.
225
226    A pivot_dimension identifies the categories associated with a single
227    dimension within a multidimensional pivot table.
228
229    A dimension contains a collection of categories, which are the leaves in a
230    tree of groups.
231
232    (A dimension or a group can contain zero categories, but this is unusual.
233    If a dimension contains no categories, then its table cannot contain any
234    data.)
235 */
236 struct pivot_dimension
237   {
238     /* table->axes[axis_type]->dimensions[level] == dimension. */
239     struct pivot_table *table;
240     enum pivot_axis_type axis_type;
241     size_t level;               /* 0 for innermost dimension within axis. */
242
243     /* table->dimensions[top_index] == dimension. */
244     size_t top_index;
245
246     /* Hierarchy of categories within the dimension.  The groups and categories
247        are sorted in the order that should be used for display.  This might be
248        different from the original order produced for output if the user
249        adjusted it.
250
251        The root must always be a group, although it is allowed to have no
252        subcategories. */
253     struct pivot_category *root;
254
255     /* All of the leaves reachable via the root.
256
257        The indexing for presentation_leaves is presentation order, thus
258        presentation_leaves[i]->presentation_index == i.  This order is the same
259        as would be produced by an in-order traversal of the groups.  It is the
260        order into which the user reordered or sorted the categories.
261
262        The indexing for data_leaves is that used for idx[] in struct
263        pivot_cell, thus data_leaves[i]->data_index == i.  This might differ
264        from what an in-order traversal of 'root' would yield, if the user
265        reordered categories. */
266     struct pivot_category **data_leaves;
267     struct pivot_category **presentation_leaves;
268     size_t n_leaves, allocated_leaves;
269
270     /* Display. */
271     bool hide_all_labels;
272
273     /* Number of rows or columns needed to express the labels. */
274     int label_depth;
275   };
276
277 struct pivot_dimension *pivot_dimension_create (
278   struct pivot_table *, enum pivot_axis_type, const char *name, ...)
279   SENTINEL (0);
280 #define pivot_dimension_create(...) \
281   pivot_dimension_create(__VA_ARGS__, NULL_SENTINEL)
282 struct pivot_dimension *pivot_dimension_create__ (struct pivot_table *,
283                                                   enum pivot_axis_type,
284                                                   struct pivot_value *name);
285
286 void pivot_dimension_destroy (struct pivot_dimension *);
287
288 void pivot_dimension_dump (const struct pivot_dimension *, int indentation);
289 \f
290 /* A pivot_category is a leaf (a category) or a group:
291
292    - For a leaf, neither index is SIZE_MAX.
293
294    - For a group, both indexes are SIZE_MAX.
295
296    Do not use 'subs' or 'n_subs' to determine whether a category is a group,
297    because a group may (pathologically) have no leaves. */
298 struct pivot_category
299   {
300     struct pivot_value *name;
301     struct pivot_category *parent;
302     struct pivot_dimension *dimension;
303     size_t label_depth, extra_depth;
304
305     /* Groups only.
306
307        If show_label is true, then the group itself has a row (or a column)
308        giving the group's name.  Otherwise, the group's own name is not
309        displayed. */
310     struct pivot_category **subs; /* Child categories or groups. */
311     size_t n_subs, allocated_subs;
312     bool show_label;            /* Display a label for the group itself? */
313     bool show_label_in_corner;
314
315     /* Leaf only. */
316     struct fmt_spec format;
317     size_t group_index;        /* In ->parent->subs[]. */
318     size_t data_index;         /* In ->dimension->data_leaves[]. */
319     size_t presentation_index; /* In ->dimension->presentation_leaves[]. */
320   };
321
322 static inline bool
323 pivot_category_is_group (const struct pivot_category *category)
324 {
325   return category->data_index == SIZE_MAX;
326 }
327
328 static inline bool
329 pivot_category_is_leaf (const struct pivot_category *category)
330 {
331   return !pivot_category_is_group (category);
332 }
333
334 /* Creating leaf categories. */
335 int pivot_category_create_leaves (struct pivot_category *parent, ...)
336   SENTINEL (0);
337 #define pivot_category_create_leaves(...) \
338   pivot_category_create_leaves(__VA_ARGS__, NULL_SENTINEL)
339
340 int pivot_category_create_leaf (
341   struct pivot_category *parent, struct pivot_value *name);
342 int pivot_category_create_leaf_rc (
343   struct pivot_category *parent, struct pivot_value *name, const char *rc);
344
345 /* Creating category groups. */
346 struct pivot_category *pivot_category_create_group (
347   struct pivot_category *parent, const char *name, ...) SENTINEL (0);
348 #define pivot_category_create_group(...) \
349   pivot_category_create_group(__VA_ARGS__, NULL_SENTINEL)
350 struct pivot_category *pivot_category_create_group__ (
351   struct pivot_category *parent, struct pivot_value *name);
352
353 void pivot_category_destroy (struct pivot_category *);
354
355 /* Pivot result classes.
356
357    These are used to mark leaf categories as having particular types of data,
358    to set their numeric formats.  The formats that actually get used for these
359    classes are in the result_classes[] global array in pivot-table.c, except
360    that PIVOT_RC_OTHER comes from settings_get_format() and PIVOT_RC_COUNT
361    should come from the weight variable in the dataset's dictionary. */
362 #define PIVOT_RC_OTHER ("RC_OTHER")
363 #define PIVOT_RC_INTEGER ("RC_INTEGER")
364 #define PIVOT_RC_CORRELATION ("RC_CORRELATIONS")
365 #define PIVOT_RC_SIGNIFICANCE ("RC_SIGNIFICANCE")
366 #define PIVOT_RC_PERCENT ("RC_PERCENT")
367 #define PIVOT_RC_RESIDUAL ("RC_RESIDUAL")
368 #define PIVOT_RC_COUNT ("RC_COUNT")
369
370 bool pivot_result_class_change (const char *, const struct fmt_spec *);
371 \f
372 /* Styling for a pivot table.
373
374    The division between this and the style information in struct pivot_table
375    seems fairly arbitrary.  The ultimate reason for the division is simply
376    because that's how SPSS documentation and file formats do it. */
377 struct pivot_table_look
378   {
379     char *name;                 /* May be null. */
380
381     /* General properties. */
382     bool omit_empty;
383     bool row_labels_in_corner;
384     int width_ranges[TABLE_N_AXES][2];      /* In 1/96" units. */
385
386     /* Footnote display settings. */
387     bool show_numeric_markers;
388     bool footnote_marker_superscripts;
389
390     /* Styles. */
391     struct table_area_style areas[PIVOT_N_AREAS];
392     struct table_border_style borders[PIVOT_N_BORDERS];
393
394     /* Print settings. */
395     bool print_all_layers;
396     bool paginate_layers;
397     bool shrink_to_fit[TABLE_N_AXES];
398     bool top_continuation, bottom_continuation;
399     char *continuation;
400     size_t n_orphan_lines;
401   };
402
403 void pivot_table_look_init (struct pivot_table_look *);
404 void pivot_table_look_uninit (struct pivot_table_look *);
405 void pivot_table_look_copy (struct pivot_table_look *,
406                             const struct pivot_table_look *);
407 \f
408 /* A pivot table.  See the top of this file for more information. */
409 struct pivot_table
410   {
411     /* Reference count.  A pivot_table may be shared between multiple owners,
412        indicated by a reference count greater than 1.  When this is the case,
413        the pivot_table must not be modified. */
414     int ref_cnt;
415
416     /* Styling. */
417     struct pivot_table_look look;
418
419     /* Display settings. */
420     bool rotate_inner_column_labels;
421     bool rotate_outer_row_labels;
422     bool show_grid_lines;
423     bool show_caption;
424     size_t *current_layer; /* axis[PIVOT_AXIS_LAYER].n_dimensions elements. */
425     enum settings_value_show show_values;
426     enum settings_value_show show_variables;
427     struct fmt_spec weight_format;
428
429     /* Column and row sizing and page breaks.
430        sizing[TABLE_HORZ] is for columns, sizing[TABLE_VERT] is for rows. */
431     struct pivot_table_sizing sizing[TABLE_N_AXES];
432
433     /* Format settings. */
434     int epoch;
435     char decimal;               /* Usually ',' or '.'. */
436     char grouping;              /* Usually '.' or ','. */
437     char *ccs[5];               /* Custom currency. */
438     double small;
439
440     /* Command information. */
441     char *command_local;        /* May be NULL. */
442     char *command_c;            /* May be NULL. */
443     char *language;             /* May be NULL. */
444     char *locale;               /* May be NULL. */
445
446     /* Source information. */
447     char *dataset;              /* May be NULL. */
448     char *datafile;             /* May be NULL. */
449     time_t date;                /* May be 0 if unknown. */
450
451     /* Footnotes. */
452     struct pivot_footnote **footnotes;
453     size_t n_footnotes, allocated_footnotes;
454
455     /* Titles. */
456     struct pivot_value *title;
457     struct pivot_value *subtype;  /* Same as spv_item's subtype. */
458     struct pivot_value *corner_text;
459     struct pivot_value *caption;
460     char *notes;
461
462     /* Dimensions. */
463     struct pivot_dimension **dimensions;
464     size_t n_dimensions;
465
466     /* Allocation of dimensions to rows, columns, and layers. */
467     struct pivot_axis axes[PIVOT_N_AXES];
468
469     struct hmap cells;          /* Contains "struct pivot_cell"s. */
470   };
471
472 /* Creating and destroy pivot tables. */
473 struct pivot_table *pivot_table_create (const char *title);
474 struct pivot_table *pivot_table_create__ (struct pivot_value *title,
475                                           const char *subtype);
476 struct pivot_table *pivot_table_create_for_text (struct pivot_value *title,
477                                                  struct pivot_value *content);
478
479 struct pivot_table *pivot_table_ref (const struct pivot_table *);
480 void pivot_table_unref (struct pivot_table *);
481 bool pivot_table_is_shared (const struct pivot_table *);
482
483 /* Styling. */
484 const struct pivot_table_look *pivot_table_get_look (
485   const struct pivot_table *);
486 void pivot_table_set_look (struct pivot_table *,
487                            const struct pivot_table_look *);
488
489 /* Format of PIVOT_RC_COUNT cells. */
490 void pivot_table_set_weight_var (struct pivot_table *,
491                                  const struct variable *);
492 void pivot_table_set_weight_format (struct pivot_table *,
493                                     const struct fmt_spec *);
494
495 /* Query. */
496 bool pivot_table_is_empty (const struct pivot_table *);
497
498 /* Output. */
499 void pivot_table_submit (struct pivot_table *);
500
501 /* Data cells. */
502 void pivot_table_put (struct pivot_table *, const size_t *dindexes, size_t n,
503                       struct pivot_value *);
504 void pivot_table_put1 (struct pivot_table *, size_t idx1,
505                        struct pivot_value *);
506 void pivot_table_put2 (struct pivot_table *, size_t idx1, size_t idx2,
507                        struct pivot_value *);
508 void pivot_table_put3 (struct pivot_table *, size_t idx1, size_t idx2,
509                        size_t idx3, struct pivot_value *);
510 void pivot_table_put4 (struct pivot_table *, size_t idx1, size_t idx2,
511                        size_t idx3, size_t idx4, struct pivot_value *);
512
513 const struct pivot_value *pivot_table_get (const struct pivot_table *,
514                                            const size_t *dindexes);
515
516 struct pivot_value *pivot_table_get_rw (struct pivot_table *,
517                                         const size_t *dindexes);
518
519 /* Footnotes.
520
521    Use pivot_table_create_footnote() to create a footnote.
522    Use pivot_value_add_footnote() to add a reference to a footnote. */
523 struct pivot_footnote
524   {
525     size_t idx;
526     struct pivot_value *content;
527     struct pivot_value *marker;
528     bool show;
529   };
530
531 struct pivot_footnote *pivot_table_create_footnote (
532   struct pivot_table *, struct pivot_value *content);
533 struct pivot_footnote *pivot_table_create_footnote__ (
534   struct pivot_table *, size_t idx,
535   struct pivot_value *marker, struct pivot_value *content);
536
537 void pivot_footnote_destroy (struct pivot_footnote *);
538
539 /* Internals. */
540 void pivot_table_convert_indexes_ptod (const struct pivot_table *,
541                                        const size_t *pindexes[PIVOT_N_AXES],
542                                        size_t *dindexes);
543 size_t *pivot_table_enumerate_axis (const struct pivot_table *,
544                                     enum pivot_axis_type,
545                                     const size_t *layer_indexes,
546                                     bool omit_empty, size_t *n);
547 #define PIVOT_ENUMERATION_FOR_EACH(INDEXES, ENUMERATION, AXIS)  \
548   for ((INDEXES) = (ENUMERATION); *(INDEXES) != SIZE_MAX;       \
549        (INDEXES) += MAX (1, (AXIS)->n_dimensions))
550
551 void pivot_table_assign_label_depth (struct pivot_table *);
552
553 void pivot_table_dump (const struct pivot_table *, int indentation);
554 \f
555 /* pivot_value. */
556
557 enum pivot_value_type
558   {
559     PIVOT_VALUE_NUMERIC,          /* A value of a numeric variable. */
560     PIVOT_VALUE_STRING,           /* A value of a string variable. */
561     PIVOT_VALUE_VARIABLE,         /* Name of a variable. */
562     PIVOT_VALUE_TEXT,             /* Text. */
563     PIVOT_VALUE_TEMPLATE,         /* Templated text. */
564   };
565
566 /* A pivot_value is the content of a single pivot table cell.  A pivot_value is
567    also a pivot table's title, caption, footnote marker and contents, and so
568    on.
569
570    A given pivot_value is one of:
571
572    1. A number resulting from a calculation (PIVOT_VALUE_NUMERIC).  Use
573       pivot_value_new_number() to create such a pivot_value.
574
575       A numeric pivot_value has an associated display format (usually an F or
576       PCT format).  This format can be set directly on the pivot_value, but
577       that is not usually the easiest way.  Instead, it is usually true that
578       all of the values in a single category should have the same format
579       (e.g. all "Significance" values might use format F40.3), so PSPP makes
580       it easy to set the default format for a category while creating the
581       category.  See pivot_dimension_create() for more details.
582
583       For numbers that should be displayed as integers,
584       pivot_value_new_integer() can occasionally be a useful special case.
585
586    2. A numeric or string value obtained from data (PIVOT_VALUE_NUMERIC or
587       PIVOT_VALUE_STRING).  If such a value corresponds to a variable, then the
588       variable's name can be attached to the pivot_value.  If the value has a
589       value label, then that can also be attached.  When a label is present,
590       the user can control whether to show the value or the label or both.
591
592       Use pivot_value_new_var_value() to create pivot_values of these kinds.
593
594    3. A variable name (PIVOT_VALUE_VARIABLE).  The variable label, if any, can
595       be attached too, and again the user can control whether to show the value
596       or the label or both.
597
598    4. A text string (PIVOT_VALUE_TEXT).  The value stores the string in English
599       and translated into the output language (localized).  Use
600       pivot_value_new_text() or pivot_value_new_text_format() for those cases.
601       In some cases, only an English or a localized version is available for
602       one reason or another, although this is regrettable; in those cases, use
603       pivot_value_new_user_text() or pivot_value_new_user_text_nocopy().
604
605    (There is also a PIVOT_VALUE_TEMPLATE but PSPP does not yet create these
606    itself.)
607
608
609    Footnotes
610    =========
611
612    A pivot_value may reference any number of footnotes.  Use
613    pivot_value_add_footnote() to add a footnote reference.  The footnotes being
614    referenced must first be created with pivot_table_create_footnote().
615
616
617    Styling
618    =======
619
620    A pivot_value can have specific font and cell styles.  Only the user should
621    add these.
622 */
623 struct pivot_value
624   {
625     struct font_style *font_style;
626     struct cell_style *cell_style;
627
628     char **subscripts;
629     size_t n_subscripts;
630
631     char *superscript;
632
633     const struct pivot_footnote **footnotes;
634     size_t n_footnotes;
635
636     enum pivot_value_type type;
637     union
638       {
639         /* PIVOT_VALUE_NUMERIC. */
640         struct
641           {
642             double x;                 /* The numeric value. */
643             struct fmt_spec format;   /* Format to display 'x'. */
644             char *var_name;           /* May be NULL. */
645             char *value_label;        /* May be NULL. */
646             enum settings_value_show show; /* Show value or label or both? */
647           }
648         numeric;
649
650         /* PIVOT_VALUE_STRING. */
651         struct
652           {
653             char *s;                  /* The string value. */
654             bool hex;                 /* Display in hex? */
655             char *var_name;           /* May be NULL. */
656             char *value_label;        /* May be NULL. */
657             enum settings_value_show show; /* Show value or label or both? */
658           }
659         string;
660
661         /* PIVOT_VALUE_VARIABLE. */
662         struct
663           {
664             char *var_name;
665             char *var_label;          /* May be NULL. */
666             enum settings_value_show show; /* Show name or label or both? */
667           }
668         variable;
669
670         /* PIVOT_VALUE_TEXT. */
671         struct
672           {
673             char *local;              /* Localized. */
674             char *c;                  /* English. */
675             char *id;                 /* Identifier. */
676             bool user_provided;
677           }
678         text;
679
680         /* PIVOT_VALUE_TEMPLATE. */
681         struct
682           {
683             char *local;              /* Localized. */
684             char *id;                 /* Identifier. */
685             struct pivot_argument *args;
686             size_t n_args;
687           }
688         template;
689       };
690   };
691
692 /* Numbers resulting from calculations. */
693 struct pivot_value *pivot_value_new_number (double);
694 struct pivot_value *pivot_value_new_integer (double);
695
696 /* Values from data. */
697 struct pivot_value *pivot_value_new_var_value (
698   const struct variable *, const union value *);
699 struct pivot_value *pivot_value_new_value (const union value *, int width,
700                                            const struct fmt_spec *,
701                                            const char *encoding);
702
703 /* Values from variable names. */
704 struct pivot_value *pivot_value_new_variable (const struct variable *);
705
706 /* Values from text strings. */
707 struct pivot_value *pivot_value_new_text (const char *);
708 struct pivot_value *pivot_value_new_text_format (const char *, ...)
709   __attribute__((format(gnu_printf, 1, 2)));
710
711 struct pivot_value *pivot_value_new_user_text (const char *, size_t length);
712 struct pivot_value *pivot_value_new_user_text_nocopy (char *);
713
714 /* Footnotes. */
715 void pivot_value_add_footnote (struct pivot_value *, const struct pivot_footnote *);
716
717 /* Numeric formats. */
718 void pivot_value_set_rc (const struct pivot_table *, struct pivot_value *,
719                          const char *rc);
720
721 /* Converting a pivot_value to a string for display. */
722 char *pivot_value_to_string (const struct pivot_value *,
723                              enum settings_value_show show_values,
724                              enum settings_value_show show_variables);
725 void pivot_value_format (const struct pivot_value *,
726                          enum settings_value_show show_values,
727                          enum settings_value_show show_variables,
728                          struct string *);
729 bool pivot_value_format_body (const struct pivot_value *,
730                               enum settings_value_show show_values,
731                               enum settings_value_show show_variables,
732                               struct string *);
733
734 void pivot_value_destroy (struct pivot_value *);
735
736 /* Styling. */
737 void pivot_value_get_style (struct pivot_value *,
738                             const struct font_style *base_font_style,
739                             const struct cell_style *base_cell_style,
740                             struct table_area_style *);
741 void pivot_value_set_style (struct pivot_value *,
742                             const struct table_area_style *);
743
744 /* Template arguments. */
745 struct pivot_argument
746   {
747     size_t n;
748     struct pivot_value **values;
749   };
750
751 void pivot_argument_uninit (struct pivot_argument *);
752 \f
753 /* One piece of data within a pivot table. */
754 struct pivot_cell
755   {
756     struct hmap_node hmap_node; /* In struct pivot_table's 'cells' hmap. */
757     struct pivot_value *value;
758     unsigned int idx[];         /* One index per table dimension. */
759   };
760
761 #endif /* output/pivot-table.h */