1 /* $Id: tree.c,v 1.91 2021/09/07 10:59:18 schwarze Exp $ */
3 * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
4 * Copyright (c) 2013-2015, 2017-2021 Ingo Schwarze <schwarze@openbsd.org>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * Formatting module to let mandoc(1) show
19 * a human readable representation of the syntax tree.
23 #include <sys/types.h>
39 static void print_attr(const struct roff_node
*);
40 static void print_box(const struct eqn_box
*, int);
41 static void print_cellt(enum tbl_cellt
);
42 static void print_man(const struct roff_node
*, int);
43 static void print_meta(const struct roff_meta
*);
44 static void print_mdoc(const struct roff_node
*, int);
45 static void print_span(const struct tbl_span
*, int);
49 tree_mdoc(void *arg
, const struct roff_meta
*mdoc
)
53 print_mdoc(mdoc
->first
->child
, 0);
57 tree_man(void *arg
, const struct roff_meta
*man
)
60 if (man
->hasbody
== 0)
63 print_man(man
->first
->child
, 0);
67 print_meta(const struct roff_meta
*meta
)
69 if (meta
->title
!= NULL
)
70 printf("title = \"%s\"\n", meta
->title
);
71 if (meta
->name
!= NULL
)
72 printf("name = \"%s\"\n", meta
->name
);
73 if (meta
->msec
!= NULL
)
74 printf("sec = \"%s\"\n", meta
->msec
);
75 if (meta
->vol
!= NULL
)
76 printf("vol = \"%s\"\n", meta
->vol
);
77 if (meta
->arch
!= NULL
)
78 printf("arch = \"%s\"\n", meta
->arch
);
80 printf("os = \"%s\"\n", meta
->os
);
81 if (meta
->date
!= NULL
)
82 printf("date = \"%s\"\n", meta
->date
);
86 print_mdoc(const struct roff_node
*n
, int indent
)
91 struct mdoc_argv
*argv
;
143 p
= roff_name
[n
->tok
];
146 p
= roff_name
[n
->tok
];
149 p
= roff_name
[n
->tok
];
152 p
= roff_name
[n
->tok
];
154 argv
= n
->args
->argv
;
155 argc
= n
->args
->argc
;
159 p
= roff_name
[n
->tok
];
161 argv
= n
->args
->argv
;
162 argc
= n
->args
->argc
;
178 assert(NULL
== p
&& NULL
== t
);
179 print_span(n
->span
, indent
);
181 for (i
= 0; i
< indent
; i
++)
184 printf("%s (%s)", p
, t
);
186 for (i
= 0; i
< (int)argc
; i
++) {
187 printf(" -%s", mdoc_argnames
[argv
[i
].arg
]);
190 for (j
= 0; j
< (int)argv
[i
].sz
; j
++)
191 printf(" [%s]", argv
[i
].value
[j
]);
198 print_box(n
->eqn
->first
, indent
+ 4);
200 print_mdoc(n
->child
, indent
+
201 (n
->type
== ROFFT_BLOCK
? 2 : 4));
203 print_mdoc(n
->next
, indent
);
207 print_man(const struct roff_node
*n
, int indent
)
257 p
= roff_name
[n
->tok
];
272 assert(NULL
== p
&& NULL
== t
);
273 print_span(n
->span
, indent
);
275 for (i
= 0; i
< indent
; i
++)
277 printf("%s (%s)", p
, t
);
281 print_box(n
->eqn
->first
, indent
+ 4);
283 print_man(n
->child
, indent
+
284 (n
->type
== ROFFT_BLOCK
? 2 : 4));
286 print_man(n
->next
, indent
);
290 print_attr(const struct roff_node
*n
)
293 if (n
->flags
& NODE_DELIMO
)
295 if (n
->flags
& NODE_LINE
)
297 printf("%d:%d", n
->line
, n
->pos
+ 1);
298 if (n
->flags
& NODE_DELIMC
)
300 if (n
->flags
& NODE_EOS
)
302 if (n
->flags
& NODE_ID
) {
304 if (n
->flags
& NODE_HREF
)
306 } else if (n
->flags
& NODE_HREF
)
308 else if (n
->tag
!= NULL
)
311 printf("=%s", n
->tag
);
312 if (n
->flags
& NODE_BROKEN
)
314 if (n
->flags
& NODE_NOFILL
)
316 if (n
->flags
& NODE_NOSRC
)
318 if (n
->flags
& NODE_NOPRT
)
324 print_box(const struct eqn_box
*ep
, int indent
)
329 static const char *posnames
[] = {
330 NULL
, "sup", "subsup", "sub",
331 "to", "from", "fromto",
332 "over", "sqrt", NULL
};
336 for (i
= 0; i
< indent
; i
++)
360 printf(" pos=%s", posnames
[ep
->pos
]);
362 printf(" left=\"%s\"", ep
->left
);
364 printf(" right=\"%s\"", ep
->right
);
366 printf(" top=\"%s\"", ep
->top
);
368 printf(" bottom=\"%s\"", ep
->bottom
);
370 printf(" text=\"%s\"", ep
->text
);
372 printf(" font=%d", ep
->font
);
373 if (ep
->size
!= EQN_DEFSIZE
)
374 printf(" size=%d", ep
->size
);
375 if (ep
->expectargs
!= UINT_MAX
&& ep
->expectargs
!= ep
->args
)
376 printf(" badargs=%zu(%zu)", ep
->args
, ep
->expectargs
);
378 printf(" args=%zu", ep
->args
);
381 print_box(ep
->first
, indent
+ 4);
382 print_box(ep
->next
, indent
);
386 print_cellt(enum tbl_cellt pos
)
395 case TBL_CELL_CENTRE
:
401 case TBL_CELL_NUMBER
:
413 case TBL_CELL_DHORIZ
:
423 print_span(const struct tbl_span
*sp
, int indent
)
425 const struct tbl_dat
*dp
;
426 const struct tbl_cell
*cp
;
429 if (sp
->prev
== NULL
) {
430 for (i
= 0; i
< indent
; i
++)
432 printf("%d", sp
->opts
->cols
);
433 if (sp
->opts
->opts
& TBL_OPT_CENTRE
)
434 fputs(" center", stdout
);
435 if (sp
->opts
->opts
& TBL_OPT_EXPAND
)
436 fputs(" expand", stdout
);
437 if (sp
->opts
->opts
& TBL_OPT_ALLBOX
)
438 fputs(" allbox", stdout
);
439 if (sp
->opts
->opts
& TBL_OPT_BOX
)
440 fputs(" box", stdout
);
441 if (sp
->opts
->opts
& TBL_OPT_DBOX
)
442 fputs(" doublebox", stdout
);
443 if (sp
->opts
->opts
& TBL_OPT_NOKEEP
)
444 fputs(" nokeep", stdout
);
445 if (sp
->opts
->opts
& TBL_OPT_NOSPACE
)
446 fputs(" nospaces", stdout
);
447 if (sp
->opts
->opts
& TBL_OPT_NOWARN
)
448 fputs(" nowarn", stdout
);
449 printf(" (tbl options) %d:1\n", sp
->line
);
452 for (i
= 0; i
< indent
; i
++)
460 case TBL_SPAN_DHORIZ
:
465 for (cp
= sp
->layout
->first
; cp
!= NULL
; cp
= cp
->next
)
466 print_cellt(cp
->pos
);
468 for (dp
= sp
->first
; dp
; dp
= dp
->next
) {
469 if ((cp
= dp
->layout
) == NULL
)
472 printf("%d", cp
->col
);
473 print_cellt(dp
->layout
->pos
);
475 case ESCAPE_FONTROMAN
:
477 case ESCAPE_FONTBOLD
:
480 case ESCAPE_FONTITALIC
:
498 if (cp
->flags
& TBL_CELL_TALIGN
)
500 if (cp
->flags
& TBL_CELL_UP
)
502 if (cp
->flags
& TBL_CELL_BALIGN
)
504 if (cp
->flags
& TBL_CELL_WIGN
)
506 if (cp
->flags
& TBL_CELL_EQUAL
)
508 if (cp
->flags
& TBL_CELL_WMAX
)
513 case TBL_DATA_NHORIZ
:
516 case TBL_DATA_DHORIZ
:
517 case TBL_DATA_NDHORIZ
:
521 putchar(dp
->block
? '{' : '[');
522 if (dp
->string
!= NULL
)
523 fputs(dp
->string
, stdout
);
524 putchar(dp
->block
? '}' : ']');
528 printf(">%d", dp
->hspans
);
530 printf("v%d", dp
->vspans
);
535 printf("(tbl) %d:1\n", sp
->line
);