]> git.cameronkatri.com Git - mandoc.git/blob - tbl_data.c
Add basic -Ttree support for tables.
[mandoc.git] / tbl_data.c
1 /* $Id: tbl_data.c,v 1.3 2010/12/30 10:26: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 #include <assert.h>
18 #include <ctype.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include "mandoc.h"
23 #include "libmandoc.h"
24 #include "libroff.h"
25
26 static void data(struct tbl *, struct tbl_span *,
27 int, const char *, int *);
28
29 void
30 data(struct tbl *tbl, struct tbl_span *dp,
31 int ln, const char *p, int *pos)
32 {
33 struct tbl_dat *dat;
34 struct tbl_cell *cp;
35 int sv;
36
37 cp = NULL;
38 if (dp->last && dp->last->layout)
39 cp = dp->last->layout->next;
40 else if (NULL == dp->last)
41 cp = dp->layout->first;
42
43 /* Skip over spanners to data formats. */
44
45 while (cp && (TBL_CELL_VERT == cp->pos ||
46 TBL_CELL_DVERT == cp->pos))
47 cp = cp->next;
48
49 /* FIXME: warn about losing data contents if cell is HORIZ. */
50
51 dat = mandoc_calloc(1, sizeof(struct tbl_dat));
52 dat->layout = cp;
53
54 if (dp->last) {
55 dp->last->next = dat;
56 dp->last = dat;
57 } else
58 dp->last = dp->first = dat;
59
60 sv = *pos;
61 while (p[*pos] && p[*pos] != tbl->tab)
62 (*pos)++;
63
64 dat->string = mandoc_malloc(*pos - sv + 1);
65 memcpy(dat->string, &p[sv], *pos - sv);
66 dat->string[*pos - sv] = '\0';
67
68 if (p[*pos])
69 (*pos)++;
70
71 /* XXX: do the strcmps, then malloc(). */
72
73 if ( ! strcmp(dat->string, "_"))
74 dat->flags |= TBL_DATA_HORIZ;
75 else if ( ! strcmp(dat->string, "="))
76 dat->flags |= TBL_DATA_DHORIZ;
77 else if ( ! strcmp(dat->string, "\\_"))
78 dat->flags |= TBL_DATA_NHORIZ;
79 else if ( ! strcmp(dat->string, "\\="))
80 dat->flags |= TBL_DATA_NDHORIZ;
81 }
82
83 int
84 tbl_data(struct tbl *tbl, int ln, const char *p)
85 {
86 struct tbl_span *dp;
87 struct tbl_row *rp;
88 int pos;
89
90 pos = 0;
91
92 if ('\0' == p[pos]) {
93 TBL_MSG(tbl, MANDOCERR_TBL, ln, pos);
94 return(1);
95 }
96
97 /*
98 * Choose a layout row: take the one following the last parsed
99 * span's. If that doesn't exist, use the last parsed span's.
100 * If there's no last parsed span, use the first row. This can
101 * be NULL!
102 */
103
104 if (tbl->last_span) {
105 assert(tbl->last_span->layout);
106 rp = tbl->last_span->layout->next;
107 if (NULL == rp)
108 rp = tbl->last_span->layout;
109 } else
110 rp = tbl->first_row;
111
112 dp = mandoc_calloc(1, sizeof(struct tbl_span));
113 dp->layout = rp;
114
115 if (tbl->last_span) {
116 tbl->last_span->next = dp;
117 tbl->last_span = dp;
118 } else
119 tbl->last_span = tbl->first_span = dp;
120
121 if ( ! strcmp(p, "_")) {
122 dp->flags |= TBL_SPAN_HORIZ;
123 return(1);
124 } else if ( ! strcmp(p, "=")) {
125 dp->flags |= TBL_SPAN_DHORIZ;
126 return(1);
127 }
128
129 while ('\0' != p[pos])
130 data(tbl, dp, ln, p, &pos);
131
132 return(1);
133 }