]> git.cameronkatri.com Git - mandoc.git/blob - tree.c
In -Tman mode, support automatic word keeps in the SYNOPSIS
[mandoc.git] / tree.c
1 /* $Id: tree.c,v 1.47 2011/09/18 14:14:15 schwarze Exp $ */
2 /*
3 * Copyright (c) 2008, 2009, 2011 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 const char *t;
267
268 if (NULL == ep)
269 return;
270 for (i = 0; i < indent; i++)
271 putchar('\t');
272
273 t = NULL;
274 switch (ep->type) {
275 case (EQN_ROOT):
276 t = "eqn-root";
277 break;
278 case (EQN_LIST):
279 t = "eqn-list";
280 break;
281 case (EQN_SUBEXPR):
282 t = "eqn-expr";
283 break;
284 case (EQN_TEXT):
285 t = "eqn-text";
286 break;
287 case (EQN_MATRIX):
288 t = "eqn-matrix";
289 break;
290 }
291
292 assert(t);
293 printf("%s(%d, %d, %d, %d, %d, \"%s\", \"%s\") %s\n",
294 t, EQN_DEFSIZE == ep->size ? 0 : ep->size,
295 ep->pos, ep->font, ep->mark, ep->pile,
296 ep->left ? ep->left : "",
297 ep->right ? ep->right : "",
298 ep->text ? ep->text : "");
299
300 print_box(ep->first, indent + 1);
301 print_box(ep->next, indent);
302 }
303
304 static void
305 print_span(const struct tbl_span *sp, int indent)
306 {
307 const struct tbl_dat *dp;
308 int i;
309
310 for (i = 0; i < indent; i++)
311 putchar('\t');
312
313 switch (sp->pos) {
314 case (TBL_SPAN_HORIZ):
315 putchar('-');
316 return;
317 case (TBL_SPAN_DHORIZ):
318 putchar('=');
319 return;
320 default:
321 break;
322 }
323
324 for (dp = sp->first; dp; dp = dp->next) {
325 switch (dp->pos) {
326 case (TBL_DATA_HORIZ):
327 /* FALLTHROUGH */
328 case (TBL_DATA_NHORIZ):
329 putchar('-');
330 continue;
331 case (TBL_DATA_DHORIZ):
332 /* FALLTHROUGH */
333 case (TBL_DATA_NDHORIZ):
334 putchar('=');
335 continue;
336 default:
337 break;
338 }
339 printf("[\"%s\"", dp->string ? dp->string : "");
340 if (dp->spans)
341 printf("(%d)", dp->spans);
342 if (NULL == dp->layout)
343 putchar('*');
344 putchar(']');
345 putchar(' ');
346 }
347
348 printf("(tbl) %d:1\n", sp->line);
349 }