]> git.cameronkatri.com Git - mandoc.git/blob - tbl_data.c
Stuff tbl_calc() into out.c so that it can be shared by all output modes
[mandoc.git] / tbl_data.c
1 /* $Id: tbl_data.c,v 1.11 2011/01/04 15:02:00 kristaps Exp $ */
2 /*
3 * Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include <assert.h>
22 #include <ctype.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <time.h>
26
27 #include "mandoc.h"
28 #include "libmandoc.h"
29 #include "libroff.h"
30
31 static int data(struct tbl_node *, struct tbl_span *,
32 int, const char *, int *);
33
34 static int
35 data(struct tbl_node *tbl, struct tbl_span *dp,
36 int ln, const char *p, int *pos)
37 {
38 struct tbl_dat *dat;
39 struct tbl_cell *cp;
40 int sv;
41
42 cp = NULL;
43 if (dp->last && dp->last->layout)
44 cp = dp->last->layout->next;
45 else if (NULL == dp->last)
46 cp = dp->layout->first;
47
48 /* Skip over spanners to data formats. */
49
50 while (cp && (TBL_CELL_VERT == cp->pos ||
51 TBL_CELL_DVERT == cp->pos))
52 cp = cp->next;
53
54 dat = mandoc_calloc(1, sizeof(struct tbl_dat));
55 dat->layout = cp;
56 dat->pos = TBL_DATA_NONE;
57
58 if (NULL == dat->layout)
59 TBL_MSG(tbl, MANDOCERR_TBLEXTRADAT, ln, *pos);
60
61 if (dp->last) {
62 dp->last->next = dat;
63 dp->last = dat;
64 } else
65 dp->last = dp->first = dat;
66
67 sv = *pos;
68 while (p[*pos] && p[*pos] != tbl->opts.tab)
69 (*pos)++;
70
71 /*
72 * Check for a continued-data scope opening. This consists of a
73 * trailing `T{' at the end of the line. Subsequent lines,
74 * until a standalone `T}', are included in our cell.
75 */
76
77 if (*pos - sv == 2 && 'T' == p[sv] && '{' == p[sv + 1]) {
78 tbl->part = TBL_PART_CDATA;
79 return(0);
80 }
81
82 dat->string = mandoc_malloc(*pos - sv + 1);
83 memcpy(dat->string, &p[sv], *pos - sv);
84 dat->string[*pos - sv] = '\0';
85
86 if (p[*pos])
87 (*pos)++;
88
89 if ( ! strcmp(dat->string, "_"))
90 dat->pos = TBL_DATA_HORIZ;
91 else if ( ! strcmp(dat->string, "="))
92 dat->pos = TBL_DATA_DHORIZ;
93 else if ( ! strcmp(dat->string, "\\_"))
94 dat->pos = TBL_DATA_NHORIZ;
95 else if ( ! strcmp(dat->string, "\\="))
96 dat->pos = TBL_DATA_NDHORIZ;
97 else
98 dat->pos = TBL_DATA_DATA;
99
100 if (NULL == dat->layout)
101 return(1);
102
103 if (TBL_CELL_HORIZ == dat->layout->pos ||
104 TBL_CELL_DHORIZ == dat->layout->pos)
105 if (TBL_DATA_DATA == dat->pos && '\0' != *dat->string)
106 TBL_MSG(tbl, MANDOCERR_TBLIGNDATA, ln, sv);
107
108 return(1);
109 }
110
111 int
112 tbl_cdata(struct tbl_node *tbl, int ln, const char *p)
113 {
114 struct tbl_dat *dat;
115 size_t sz;
116
117 if (0 == strcmp(p, "T}")) {
118 tbl->part = TBL_PART_DATA;
119 return(1);
120 }
121
122 dat = tbl->last_span->last;
123 dat->pos = TBL_DATA_DATA;
124
125 if (dat->string) {
126 sz = strlen(p) + strlen(dat->string) + 2;
127 dat->string = mandoc_realloc(dat->string, sz);
128 strlcat(dat->string, " ", sz);
129 strlcat(dat->string, p, sz);
130 } else
131 dat->string = mandoc_strdup(p);
132
133 return(0);
134 }
135
136 int
137 tbl_data(struct tbl_node *tbl, int ln, const char *p)
138 {
139 struct tbl_span *dp;
140 struct tbl_row *rp;
141 int pos;
142
143 pos = 0;
144
145 if ('\0' == p[pos]) {
146 TBL_MSG(tbl, MANDOCERR_TBL, ln, pos);
147 return(0);
148 }
149
150 /*
151 * Choose a layout row: take the one following the last parsed
152 * span's. If that doesn't exist, use the last parsed span's.
153 * If there's no last parsed span, use the first row. This can
154 * be NULL!
155 */
156
157 if (tbl->last_span) {
158 assert(tbl->last_span->layout);
159 rp = tbl->last_span->layout->next;
160 if (NULL == rp)
161 rp = tbl->last_span->layout;
162 } else
163 rp = tbl->first_row;
164
165 dp = mandoc_calloc(1, sizeof(struct tbl_span));
166 dp->tbl = &tbl->opts;
167 dp->layout = rp;
168 dp->head = tbl->first_head;
169
170 if (tbl->last_span) {
171 tbl->last_span->next = dp;
172 tbl->last_span = dp;
173 } else {
174 tbl->last_span = tbl->first_span = dp;
175 dp->flags |= TBL_SPAN_FIRST;
176 }
177
178 if ( ! strcmp(p, "_")) {
179 dp->pos = TBL_SPAN_HORIZ;
180 return(1);
181 } else if ( ! strcmp(p, "=")) {
182 dp->pos = TBL_SPAN_DHORIZ;
183 return(1);
184 }
185
186 dp->pos = TBL_SPAN_DATA;
187
188 /* This returns 0 when TBL_PART_CDATA is entered. */
189
190 while ('\0' != p[pos])
191 if ( ! data(tbl, dp, ln, p, &pos))
192 return(0);
193
194 return(1);
195 }