output: Expand footnote support.
[pspp] / src / output / table-provider.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997, 1998, 1999, 2000, 2009, 2011, 2013, 2014, 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_TABLE_PROVIDER
18 #define OUTPUT_TABLE_PROVIDER 1
19
20 #include "output/table.h"
21
22 struct string;
23
24 struct footnote
25   {
26     size_t idx;
27     char *content;
28     char *marker;
29   };
30
31 /* An item of contents within a table cell. */
32 struct cell_contents
33   {
34     unsigned int options;       /* TAB_*. */
35     char *text;                 /* A paragraph of text. */
36
37     /* Optional footnote(s). */
38     const struct footnote **footnotes;
39     size_t n_footnotes;
40   };
41
42 void cell_contents_format_footnote_markers (const struct cell_contents *,
43                                             struct string *);
44
45 /* A cell in a table. */
46 struct table_cell
47   {
48     /* Occupied table region.
49
50        d[TABLE_HORZ][0] is the leftmost column.
51        d[TABLE_HORZ][1] is the rightmost column, plus 1.
52        d[TABLE_VERT][0] is the top row.
53        d[TABLE_VERT][1] is the bottom row, plus 1.
54
55        For an ordinary cell:
56            d[TABLE_HORZ][1] == d[TABLE_HORZ][0] + 1
57        and d[TABLE_VERT][1] == d[TABLE_VERT][0] + 1
58
59        For a joined cell:
60           d[TABLE_HORZ][1] > d[TABLE_HORZ][0] + 1
61        or d[TABLE_VERT][1] > d[TABLE_VERT][0] + 1
62        or both. */
63     int d[TABLE_N_AXES][2];
64
65     /* The cell's contents.
66
67        Most table cells contain only one item (a paragraph of text), but cells
68        are allowed to be empty (n_contents == 0) or contain a nested table, or
69        multiple items.
70
71        'inline_contents' provides a place to store a single item to handle the
72        common case.
73     */
74     const struct cell_contents *contents;
75     size_t n_contents;
76     struct cell_contents inline_contents;
77
78     /* Called to free the cell's data, if nonnull. */
79     void (*destructor) (void *destructor_aux);
80     void *destructor_aux;
81   };
82
83 void table_cell_free (struct table_cell *);
84
85 /* Returns the number of columns that CELL spans.  This is 1 for an ordinary
86    cell and greater than one for a cell that joins multiple columns. */
87 static inline int
88 table_cell_colspan (const struct table_cell *cell)
89 {
90   return cell->d[TABLE_HORZ][1] - cell->d[TABLE_HORZ][0];
91 }
92
93 /* Returns the number of rows that CELL spans.  This is 1 for an ordinary cell
94    and greater than one for a cell that joins multiple rows. */
95 static inline int
96 table_cell_rowspan (const struct table_cell *cell)
97 {
98   return cell->d[TABLE_VERT][1] - cell->d[TABLE_VERT][0];
99 }
100
101 /* Returns true if CELL is a joined cell, that is, if it spans multiple rows
102    or columns.  Otherwise, returns false. */
103 static inline bool
104 table_cell_is_joined (const struct table_cell *cell)
105 {
106   return table_cell_colspan (cell) > 1 || table_cell_rowspan (cell) > 1;
107 }
108 \f
109 /* Declarations to allow defining table classes. */
110
111 struct table_class
112   {
113     /* Frees TABLE.
114
115        The table class may assume that any cells that were retrieved by calling
116        the 'get_cell' function have been freed (by calling their destructors)
117        before this function is called. */
118     void (*destroy) (struct table *table);
119
120     /* Initializes CELL with the contents of the table cell at column X and row
121        Y within TABLE.  All members of CELL must be initialized, except that if
122        'destructor' is set to a null pointer, then 'destructor_aux' need not be
123        initialized.  The 'contents' member of CELL must be set to a nonnull
124        value.
125
126        The table class must allow any number of cells in the table to be
127        retrieved simultaneously; that is, TABLE must not assume that a given
128        cell will be freed before another one is retrieved using 'get_cell'.
129
130        The table class must allow joined cells to be retrieved, with identical
131        contents, using any (X,Y) location inside the cell.
132
133        The table class must not allow cells to overlap.
134
135        The table class should not allow a joined cell to cross the border
136        between header rows/columns and the interior of the table.  That is, a
137        joined cell should be entirely within headers rows and columns or
138        entirely outside them.
139
140        The table class may assume that CELL will be freed before TABLE is
141        destroyed. */
142     void (*get_cell) (const struct table *table, int x, int y,
143                       struct table_cell *cell);
144
145     /* Returns one of the TAL_* enumeration constants (declared in
146        output/table.h) representing a rule running alongside one of the cells
147        in TABLE.
148
149        See table_get_rule() in table.c for a detailed explanation of the
150        meaning of AXIS and X and Y, including a diagram. */
151     int (*get_rule) (const struct table *table,
152                      enum table_axis axis, int x, int y);
153
154     /* This function is optional and most table classes will not implement it.
155
156        If provided, this function must take ownership of A and B and return a
157        table that consists of tables A and B "pasted together", that is, a
158        table whose size is the sum of the sizes of A and B along the axis
159        specified by ORIENTATION.  A and B will ordinarily have the same size
160        along the axis opposite ORIENTATION; no particular handling of tables
161        that have different sizes along that axis is required.
162
163        The handling of rules at the seam between A and B is not specified, but
164        table_rule_combine() is one reasonable way to do it.
165
166        Called only if neither A and B is shared (as returned by
167        table_is_shared()).
168
169        Called if A or B or both is of the class defined by this table class.
170        That is, the implementation must be prepared to deal with the case where
171        A or B is not the ordinarily expected table class.
172
173        This function may return a null pointer if it cannot implement the paste
174        operation, in which case the caller will use a fallback
175        implementation.
176
177        This function is used to implement table_paste(). */
178     struct table *(*paste) (struct table *a, struct table *b,
179                             enum table_axis orientation);
180
181     /* This function is optional and most table classes will not implement it.
182
183        If provided, this function must take ownership of TABLE and return a new
184        table whose contents are the TABLE's rows RECT[TABLE_VERT][0] through
185        RECT[TABLE_VERT][1], exclusive, and the TABLE's columns
186        RECT[TABLE_HORZ][0] through RECT[TABLE_HORZ][1].
187
188        Called only if TABLE is not shared (as returned by table_is_shared()).
189
190        This function may return a null pointer if it cannot implement the
191        select operation, in which case the caller will use a fallback
192        implementation.
193
194        This function is used to implement table_select(). */
195     struct table *(*select) (struct table *table, int rect[TABLE_N_AXES][2]);
196   };
197
198 void table_init (struct table *, const struct table_class *);
199
200 /* Table class implementations can call these functions or just set the
201    table's n[] and h[][] members directly. */
202 void table_set_nc (struct table *, int nc);
203 void table_set_nr (struct table *, int nr);
204 \f
205 /* For use primarily by output drivers. */
206
207 void table_get_cell (const struct table *, int x, int y, struct table_cell *);
208 int table_get_rule (const struct table *, enum table_axis, int x, int y);
209 size_t table_collect_footnotes (const struct table_item *,
210                                 const struct footnote ***);
211
212 #endif /* output/table-provider.h */