]> git.cameronkatri.com Git - mandoc.git/blob - tree.c
Add support for 1/2, 1/4, and 3/4 (needed by eqn).
[mandoc.git] / tree.c
1 /* $Id: tree.c,v 1.45 2011/07/22 09:57:04 kristaps Exp $ */
2 /*
3 * Copyright (c) 2008, 2009 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 <limits.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <time.h>
26
27 #include "mandoc.h"
28 #include "mdoc.h"
29 #include "man.h"
30 #include "main.h"
31
32 static void print_box(const struct eqn_box *, int);
33 static void print_man(const struct man_node *, int);
34 static void print_mdoc(const struct mdoc_node *, int);
35 static void print_span(const struct tbl_span *, int);
36
37
38 /* ARGSUSED */
39 void
40 tree_mdoc(void *arg, const struct mdoc *mdoc)
41 {
42
43 print_mdoc(mdoc_node(mdoc), 0);
44 }
45
46
47 /* ARGSUSED */
48 void
49 tree_man(void *arg, const struct man *man)
50 {
51
52 print_man(man_node(man), 0);
53 }
54
55
56 static void
57 print_mdoc(const struct mdoc_node *n, int indent)
58 {
59 const char *p, *t;
60 int i, j;
61 size_t argc, sz;
62 char **params;
63 struct mdoc_argv *argv;
64
65 argv = NULL;
66 argc = sz = 0;
67 params = NULL;
68 t = p = NULL;
69
70 switch (n->type) {
71 case (MDOC_ROOT):
72 t = "root";
73 break;
74 case (MDOC_BLOCK):
75 t = "block";
76 break;
77 case (MDOC_HEAD):
78 t = "block-head";
79 break;
80 case (MDOC_BODY):
81 if (n->end)
82 t = "body-end";
83 else
84 t = "block-body";
85 break;
86 case (MDOC_TAIL):
87 t = "block-tail";
88 break;
89 case (MDOC_ELEM):
90 t = "elem";
91 break;
92 case (MDOC_TEXT):
93 t = "text";
94 break;
95 case (MDOC_TBL):
96 /* FALLTHROUGH */
97 case (MDOC_EQN):
98 break;
99 default:
100 abort();
101 /* NOTREACHED */
102 }
103
104 switch (n->type) {
105 case (MDOC_TEXT):
106 p = n->string;
107 break;
108 case (MDOC_BODY):
109 p = mdoc_macronames[n->tok];
110 break;
111 case (MDOC_HEAD):
112 p = mdoc_macronames[n->tok];
113 break;
114 case (MDOC_TAIL):
115 p = mdoc_macronames[n->tok];
116 break;
117 case (MDOC_ELEM):
118 p = mdoc_macronames[n->tok];
119 if (n->args) {
120 argv = n->args->argv;
121 argc = n->args->argc;
122 }
123 break;
124 case (MDOC_BLOCK):
125 p = mdoc_macronames[n->tok];
126 if (n->args) {
127 argv = n->args->argv;
128 argc = n->args->argc;
129 }
130 break;
131 case (MDOC_TBL):
132 /* FALLTHROUGH */
133 case (MDOC_EQN):
134 break;
135 case (MDOC_ROOT):
136 p = "root";
137 break;
138 default:
139 abort();
140 /* NOTREACHED */
141 }
142
143 if (n->span) {
144 assert(NULL == p && NULL == t);
145 print_span(n->span, indent);
146 } else if (n->eqn) {
147 assert(NULL == p && NULL == t);
148 print_box(n->eqn->root, indent);
149 } else {
150 for (i = 0; i < indent; i++)
151 putchar('\t');
152
153 printf("%s (%s)", p, t);
154
155 for (i = 0; i < (int)argc; i++) {
156 printf(" -%s", mdoc_argnames[argv[i].arg]);
157 if (argv[i].sz > 0)
158 printf(" [");
159 for (j = 0; j < (int)argv[i].sz; j++)
160 printf(" [%s]", argv[i].value[j]);
161 if (argv[i].sz > 0)
162 printf(" ]");
163 }
164
165 for (i = 0; i < (int)sz; i++)
166 printf(" [%s]", params[i]);
167
168 printf(" %d:%d\n", n->line, n->pos);
169 }
170
171 if (n->child)
172 print_mdoc(n->child, indent + 1);
173 if (n->next)
174 print_mdoc(n->next, indent);
175 }
176
177
178 static void
179 print_man(const struct man_node *n, int indent)
180 {
181 const char *p, *t;
182 int i;
183
184 t = p = NULL;
185
186 switch (n->type) {
187 case (MAN_ROOT):
188 t = "root";
189 break;
190 case (MAN_ELEM):
191 t = "elem";
192 break;
193 case (MAN_TEXT):
194 t = "text";
195 break;
196 case (MAN_BLOCK):
197 t = "block";
198 break;
199 case (MAN_HEAD):
200 t = "block-head";
201 break;
202 case (MAN_BODY):
203 t = "block-body";
204 break;
205 case (MAN_TAIL):
206 t = "block-tail";
207 break;
208 case (MAN_TBL):
209 /* FALLTHROUGH */
210 case (MAN_EQN):
211 break;
212 default:
213 abort();
214 /* NOTREACHED */
215 }
216
217 switch (n->type) {
218 case (MAN_TEXT):
219 p = n->string;
220 break;
221 case (MAN_ELEM):
222 /* FALLTHROUGH */
223 case (MAN_BLOCK):
224 /* FALLTHROUGH */
225 case (MAN_HEAD):
226 /* FALLTHROUGH */
227 case (MAN_TAIL):
228 /* FALLTHROUGH */
229 case (MAN_BODY):
230 p = man_macronames[n->tok];
231 break;
232 case (MAN_ROOT):
233 p = "root";
234 break;
235 case (MAN_TBL):
236 /* FALLTHROUGH */
237 case (MAN_EQN):
238 break;
239 default:
240 abort();
241 /* NOTREACHED */
242 }
243
244 if (n->span) {
245 assert(NULL == p && NULL == t);
246 print_span(n->span, indent);
247 } else if (n->eqn) {
248 assert(NULL == p && NULL == t);
249 print_box(n->eqn->root, indent);
250 } else {
251 for (i = 0; i < indent; i++)
252 putchar('\t');
253 printf("%s (%s) %d:%d\n", p, t, n->line, n->pos);
254 }
255
256 if (n->child)
257 print_man(n->child, indent + 1);
258 if (n->next)
259 print_man(n->next, indent);
260 }
261
262 static void
263 print_box(const struct eqn_box *ep, int indent)
264 {
265 int i;
266
267 if (NULL == ep)
268 return;
269 for (i = 0; i < indent; i++)
270 putchar('\t');
271
272 switch (ep->type) {
273 case (EQN_ROOT):
274 printf("eqn-root(%d, %d, %d, %d)\n",
275 EQN_DEFSIZE == ep->size ? 0 : ep->size,
276 ep->pos, ep->font, ep->mark);
277 print_box(ep->first, indent + 1);
278 break;
279 case (EQN_LIST):
280 printf("eqn-list(%d, %d, %d, %d, %d, %d, \"%s\", \"%s\")\n",
281 EQN_DEFSIZE == ep->size ? 0 : ep->size,
282 ep->pos, ep->font, ep->mark,
283 ep->pile, ep->above,
284 ep->left ? ep->left : "",
285 ep->right ? ep->right : "");
286 print_box(ep->first, indent + 1);
287 break;
288 case (EQN_SUBEXPR):
289 printf("eqn-subxpr(%d, %d, %d, %d, %d, %d, \"%s\", \"%s\")\n",
290 EQN_DEFSIZE == ep->size ? 0 : ep->size,
291 ep->pos, ep->font, ep->mark,
292 ep->pile, ep->above,
293 ep->left ? ep->left : "",
294 ep->right ? ep->right : "");
295 print_box(ep->first, indent + 1);
296 break;
297 case (EQN_TEXT):
298 printf("eqn-text(%d, %d, %d, %d): [%s]\n",
299 EQN_DEFSIZE == ep->size ? 0 : ep->size,
300 ep->pos, ep->font, ep->mark, ep->text);
301 break;
302 default:
303 break;
304 }
305
306 print_box(ep->next, indent);
307 }
308
309 static void
310 print_span(const struct tbl_span *sp, int indent)
311 {
312 const struct tbl_dat *dp;
313 int i;
314
315 for (i = 0; i < indent; i++)
316 putchar('\t');
317
318 switch (sp->pos) {
319 case (TBL_SPAN_HORIZ):
320 putchar('-');
321 return;
322 case (TBL_SPAN_DHORIZ):
323 putchar('=');
324 return;
325 default:
326 break;
327 }
328
329 for (dp = sp->first; dp; dp = dp->next) {
330 switch (dp->pos) {
331 case (TBL_DATA_HORIZ):
332 /* FALLTHROUGH */
333 case (TBL_DATA_NHORIZ):
334 putchar('-');
335 continue;
336 case (TBL_DATA_DHORIZ):
337 /* FALLTHROUGH */
338 case (TBL_DATA_NDHORIZ):
339 putchar('=');
340 continue;
341 default:
342 break;
343 }
344 printf("[\"%s\"", dp->string ? dp->string : "");
345 if (dp->spans)
346 printf("(%d)", dp->spans);
347 if (NULL == dp->layout)
348 putchar('*');
349 putchar(']');
350 putchar(' ');
351 }
352
353 printf("(tbl) %d:1\n", sp->line);
354 }