]> git.cameronkatri.com Git - mandoc.git/blob - termact.c
BROKEN BUILD: migrating to mmain stuff.
[mandoc.git] / termact.c
1 /* $Id: termact.c,v 1.6 2009/02/22 19:23:48 kristaps Exp $ */
2 /*
3 * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
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
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19 #include <assert.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include "term.h"
24
25 #define INDENT 4
26
27 /*
28 * Performs actions on nodes of the abstract syntax tree. Both pre- and
29 * post-fix operations are defined here.
30 */
31
32 #define TTYPE_PROG 0
33 #define TTYPE_CMD_FLAG 1
34 #define TTYPE_CMD_ARG 2
35 #define TTYPE_SECTION 3
36 #define TTYPE_FUNC_DECL 4
37 #define TTYPE_VAR_DECL 5
38 #define TTYPE_FUNC_TYPE 6
39 #define TTYPE_FUNC_NAME 7
40 #define TTYPE_FUNC_ARG 8
41 #define TTYPE_LINK 9
42 #define TTYPE_NMAX 10
43
44 /*
45 * These define "styles" for element types, like command arguments or
46 * executable names. This is useful when multiple macros must decorate
47 * the same thing (like .Ex -std cmd and .Nm cmd).
48 */
49
50 const int ttypes[TTYPE_NMAX] = {
51 TERMP_BOLD, /* TTYPE_PROG */
52 TERMP_BOLD, /* TTYPE_CMD_FLAG */
53 TERMP_UNDERLINE, /* TTYPE_CMD_ARG */
54 TERMP_BOLD, /* TTYPE_SECTION */
55 TERMP_BOLD, /* TTYPE_FUNC_DECL */
56 TERMP_UNDERLINE, /* TTYPE_VAR_DECL */
57 TERMP_UNDERLINE, /* TTYPE_FUNC_TYPE */
58 TERMP_BOLD, /* TTYPE_FUNC_NAME */
59 TERMP_UNDERLINE, /* TTYPE_FUNC_ARG */
60 TERMP_UNDERLINE /* TTYPE_LINK */
61 };
62
63 static int arg_hasattr(int, size_t,
64 const struct mdoc_arg *);
65 static int arg_getattr(int, size_t,
66 const struct mdoc_arg *);
67 static size_t arg_offset(const char *);
68
69 /*
70 * What follows describes prefix and postfix operations for the abstract
71 * syntax tree descent.
72 */
73
74 #define DECL_ARGS \
75 struct termp *p, \
76 const struct mdoc_meta *meta, \
77 const struct mdoc_node *node
78
79 #define DECL_PRE(name) \
80 static int name##_pre(DECL_ARGS)
81 #define DECL_POST(name) \
82 static void name##_post(DECL_ARGS)
83
84 DECL_PRE(termp_aq);
85 DECL_PRE(termp_ar);
86 DECL_PRE(termp_bd);
87 DECL_PRE(termp_d1);
88 DECL_PRE(termp_dq);
89 DECL_PRE(termp_ex);
90 DECL_PRE(termp_fa);
91 DECL_PRE(termp_fd);
92 DECL_PRE(termp_fl);
93 DECL_PRE(termp_fn);
94 DECL_PRE(termp_ft);
95 DECL_PRE(termp_it);
96 DECL_PRE(termp_nd);
97 DECL_PRE(termp_nm);
98 DECL_PRE(termp_ns);
99 DECL_PRE(termp_nx);
100 DECL_PRE(termp_op);
101 DECL_PRE(termp_ox);
102 DECL_PRE(termp_pf);
103 DECL_PRE(termp_pp);
104 DECL_PRE(termp_qq);
105 DECL_PRE(termp_sh);
106 DECL_PRE(termp_sq);
107 DECL_PRE(termp_sx);
108 DECL_PRE(termp_ud);
109 DECL_PRE(termp_va);
110 DECL_PRE(termp_vt);
111 DECL_PRE(termp_xr);
112
113 DECL_POST(termp_aq);
114 DECL_POST(termp_ar);
115 DECL_POST(termp_bl);
116 DECL_POST(termp_d1);
117 DECL_POST(termp_dq);
118 DECL_POST(termp_fa);
119 DECL_POST(termp_fd);
120 DECL_POST(termp_fl);
121 DECL_POST(termp_fn);
122 DECL_POST(termp_ft);
123 DECL_POST(termp_it);
124 DECL_POST(termp_nm);
125 DECL_POST(termp_op);
126 DECL_POST(termp_pf);
127 DECL_POST(termp_qq);
128 DECL_POST(termp_sh);
129 DECL_POST(termp_sq);
130 DECL_POST(termp_sx);
131 DECL_POST(termp_va);
132 DECL_POST(termp_vt);
133
134 const struct termact __termacts[MDOC_MAX] = {
135 { NULL, NULL }, /* \" */
136 { NULL, NULL }, /* Dd */
137 { NULL, NULL }, /* Dt */
138 { NULL, NULL }, /* Os */
139 { termp_sh_pre, termp_sh_post }, /* Sh */
140 { NULL, NULL }, /* Ss */
141 { termp_pp_pre, NULL }, /* Pp */
142 { termp_d1_pre, termp_d1_post }, /* D1 */
143 { NULL, NULL }, /* Dl */
144 { termp_bd_pre, NULL }, /* Bd */
145 { NULL, NULL }, /* Ed */
146 { NULL, termp_bl_post }, /* Bl */
147 { NULL, NULL }, /* El */
148 { termp_it_pre, termp_it_post }, /* It */
149 { NULL, NULL }, /* Ad */
150 { NULL, NULL }, /* An */
151 { termp_ar_pre, termp_ar_post }, /* Ar */
152 { NULL, NULL }, /* Cd */
153 { NULL, NULL }, /* Cm */
154 { NULL, NULL }, /* Dv */
155 { NULL, NULL }, /* Er */
156 { NULL, NULL }, /* Ev */
157 { termp_ex_pre, NULL }, /* Ex */
158 { termp_fa_pre, termp_fa_post }, /* Fa */
159 { termp_fd_pre, termp_fd_post }, /* Fd */
160 { termp_fl_pre, termp_fl_post }, /* Fl */
161 { termp_fn_pre, termp_fn_post }, /* Fn */
162 { termp_ft_pre, termp_ft_post }, /* Ft */
163 { NULL, NULL }, /* Ic */
164 { NULL, NULL }, /* In */
165 { NULL, NULL }, /* Li */
166 { termp_nd_pre, NULL }, /* Nd */
167 { termp_nm_pre, termp_nm_post }, /* Nm */
168 { termp_op_pre, termp_op_post }, /* Op */
169 { NULL, NULL }, /* Ot */
170 { NULL, NULL }, /* Pa */
171 { NULL, NULL }, /* Rv */
172 { NULL, NULL }, /* St */
173 { termp_va_pre, termp_va_post }, /* Va */
174 { termp_vt_pre, termp_vt_post }, /* Vt */
175 { termp_xr_pre, NULL }, /* Xr */
176 { NULL, NULL }, /* %A */
177 { NULL, NULL }, /* %B */
178 { NULL, NULL }, /* %D */
179 { NULL, NULL }, /* %I */
180 { NULL, NULL }, /* %J */
181 { NULL, NULL }, /* %N */
182 { NULL, NULL }, /* %O */
183 { NULL, NULL }, /* %P */
184 { NULL, NULL }, /* %R */
185 { NULL, NULL }, /* %T */
186 { NULL, NULL }, /* %V */
187 { NULL, NULL }, /* Ac */
188 { NULL, NULL }, /* Ao */
189 { termp_aq_pre, termp_aq_post }, /* Aq */
190 { NULL, NULL }, /* At */
191 { NULL, NULL }, /* Bc */
192 { NULL, NULL }, /* Bf */
193 { NULL, NULL }, /* Bo */
194 { NULL, NULL }, /* Bq */
195 { NULL, NULL }, /* Bsx */
196 { NULL, NULL }, /* Bx */
197 { NULL, NULL }, /* Db */
198 { NULL, NULL }, /* Dc */
199 { NULL, NULL }, /* Do */
200 { termp_dq_pre, termp_dq_post }, /* Dq */
201 { NULL, NULL }, /* Ec */
202 { NULL, NULL }, /* Ef */
203 { NULL, NULL }, /* Em */
204 { NULL, NULL }, /* Eo */
205 { NULL, NULL }, /* Fx */
206 { NULL, NULL }, /* Ms */
207 { NULL, NULL }, /* No */
208 { termp_ns_pre, NULL }, /* Ns */
209 { termp_nx_pre, NULL }, /* Nx */
210 { termp_ox_pre, NULL }, /* Ox */
211 { NULL, NULL }, /* Pc */
212 { termp_pf_pre, termp_pf_post }, /* Pf */
213 { NULL, NULL }, /* Po */
214 { NULL, NULL }, /* Pq */
215 { NULL, NULL }, /* Qc */
216 { NULL, NULL }, /* Ql */
217 { NULL, NULL }, /* Qo */
218 { termp_qq_pre, termp_qq_post }, /* Qq */
219 { NULL, NULL }, /* Re */
220 { NULL, NULL }, /* Rs */
221 { NULL, NULL }, /* Sc */
222 { NULL, NULL }, /* So */
223 { termp_sq_pre, termp_sq_post }, /* Sq */
224 { NULL, NULL }, /* Sm */
225 { termp_sx_pre, termp_sx_post }, /* Sx */
226 { NULL, NULL }, /* Sy */
227 { NULL, NULL }, /* Tn */
228 { NULL, NULL }, /* Ux */
229 { NULL, NULL }, /* Xc */
230 { NULL, NULL }, /* Xo */
231 { NULL, NULL }, /* Fo */
232 { NULL, NULL }, /* Fc */
233 { NULL, NULL }, /* Oo */
234 { NULL, NULL }, /* Oc */
235 { NULL, NULL }, /* Bk */
236 { NULL, NULL }, /* Ek */
237 { NULL, NULL }, /* Bt */
238 { NULL, NULL }, /* Hf */
239 { NULL, NULL }, /* Fr */
240 { termp_ud_pre, NULL }, /* Ud */
241 };
242
243 const struct termact *termacts = __termacts;
244
245
246 static size_t
247 arg_offset(const char *v)
248 {
249 if (0 == strcmp(v, "indent"))
250 return(INDENT);
251 if (0 == strcmp(v, "indent-two"))
252 return(INDENT * 2);
253
254 /* TODO */
255 return(0);
256 }
257
258
259 static int
260 arg_hasattr(int arg, size_t argc, const struct mdoc_arg *argv)
261 {
262
263 return(-1 != arg_getattr(arg, argc, argv));
264 }
265
266
267 static int
268 arg_getattr(int arg, size_t argc, const struct mdoc_arg *argv)
269 {
270 int i;
271
272 for (i = 0; i < (int)argc; i++)
273 if (argv[i].arg == arg)
274 return(i);
275 return(-1);
276 }
277
278
279 /* ARGSUSED */
280 static int
281 termp_dq_pre(DECL_ARGS)
282 {
283
284 if (MDOC_BODY != node->type)
285 return(1);
286
287 word(p, "``");
288 p->flags |= TERMP_NOSPACE;
289 return(1);
290 }
291
292
293 /* ARGSUSED */
294 static void
295 termp_dq_post(DECL_ARGS)
296 {
297
298 if (MDOC_BODY != node->type)
299 return;
300
301 p->flags |= TERMP_NOSPACE;
302 word(p, "''");
303 }
304
305
306 /* ARGSUSED */
307 static void
308 termp_it_post(DECL_ARGS)
309 {
310 const struct mdoc_node *n, *it;
311 const struct mdoc_block *bl;
312 int i;
313 size_t width;
314
315 /*
316 * This (and termp_it_pre()) are the most complicated functions
317 * here. They must account for a considerable number of
318 * switches that completely change the output behaviour, like
319 * -tag versus -column. Yech.
320 */
321
322 switch (node->type) {
323 case (MDOC_BODY):
324 /* FALLTHROUGH */
325 case (MDOC_HEAD):
326 break;
327 default:
328 return;
329 }
330
331 it = node->parent;
332 assert(MDOC_BLOCK == it->type);
333 assert(MDOC_It == it->tok);
334
335 n = it->parent;
336 assert(MDOC_BODY == n->type);
337 assert(MDOC_Bl == n->tok);
338 n = n->parent;
339 bl = &n->data.block;
340
341 /* If `-tag', adjust our margins accordingly. */
342
343 if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
344 i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
345 assert(i >= 0);
346 assert(1 == bl->argv[i].sz);
347 width = strlen(*bl->argv[i].value); /* XXX */
348
349 if (MDOC_HEAD == node->type) {
350 flushln(p);
351 /* FIXME: nested lists. */
352 p->rmargin = p->maxrmargin;
353 p->flags &= ~TERMP_NOBREAK;
354 } else {
355 flushln(p);
356 p->offset -= width + 1;
357 p->flags &= ~TERMP_NOLPAD;
358 }
359 return;
360 }
361
362 if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
363 i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
364 assert(i >= 0);
365 assert(1 == bl->argv[i].sz);
366 width = arg_offset(*bl->argv[i].value);
367
368 flushln(p);
369 p->offset -= width + 1;
370 return;
371 }
372 }
373
374
375 /* ARGSUSED */
376 static int
377 termp_it_pre(DECL_ARGS)
378 {
379 const struct mdoc_node *n, *it;
380 const struct mdoc_block *bl;
381 int i;
382 size_t width;
383
384 /*
385 * Also see termp_it_post() for general comments.
386 */
387
388 switch (node->type) {
389 case (MDOC_BODY):
390 /* FALLTHROUGH */
391 case (MDOC_HEAD):
392 it = node->parent;
393 break;
394 case (MDOC_BLOCK):
395 it = node;
396 break;
397 default:
398 return(1);
399 }
400
401 assert(MDOC_BLOCK == it->type);
402 assert(MDOC_It == it->tok);
403
404 n = it->parent;
405 assert(MDOC_BODY == n->type);
406 assert(MDOC_Bl == n->tok);
407 n = n->parent;
408 bl = &n->data.block;
409
410 /* If `-compact', don't assert vertical space. */
411
412 if (MDOC_BLOCK == node->type) {
413 if (arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
414 newln(p);
415 else
416 vspace(p);
417 return(1);
418 }
419
420 assert(MDOC_HEAD == node->type
421 || MDOC_BODY == node->type);
422
423 /* If `-tag', adjust our margins accordingly. */
424
425 if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
426 i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
427 assert(i >= 0); /* XXX */
428 assert(1 == bl->argv[i].sz);
429 width = strlen(*bl->argv[i].value); /* XXX */
430
431 /* FIXME: nested lists. */
432
433 if (MDOC_HEAD == node->type) {
434 p->flags |= TERMP_NOBREAK;
435 p->flags |= TERMP_NOSPACE;
436 p->rmargin = p->offset + width;
437 } else {
438 p->flags |= TERMP_NOSPACE;
439 p->flags |= TERMP_NOLPAD;
440 p->offset += width + 1;
441 }
442 return(1);
443 }
444
445 /* If `-ohang', adjust left-margin. */
446
447 if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
448 i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
449 assert(i >= 0);
450 assert(1 == bl->argv[i].sz);
451 width = arg_offset(*bl->argv[i].value);
452
453 p->flags |= TERMP_NOSPACE;
454 p->offset += width + 1;
455 return(1);
456 }
457
458 return(1);
459 }
460
461
462 /* ARGSUSED */
463 static void
464 termp_nm_post(DECL_ARGS)
465 {
466
467 p->flags &= ~ttypes[TTYPE_PROG];
468 }
469
470
471 /* ARGSUSED */
472 static void
473 termp_fl_post(DECL_ARGS)
474 {
475
476 p->flags &= ~ttypes[TTYPE_CMD_FLAG];
477 }
478
479
480 /* ARGSUSED */
481 static int
482 termp_ar_pre(DECL_ARGS)
483 {
484
485 p->flags |= ttypes[TTYPE_CMD_ARG];
486 if (NULL == node->child)
487 word(p, "...");
488 return(1);
489 }
490
491
492 /* ARGSUSED */
493 static int
494 termp_nm_pre(DECL_ARGS)
495 {
496
497 p->flags |= ttypes[TTYPE_PROG];
498 if (NULL == node->child)
499 word(p, meta->name);
500 return(1);
501 }
502
503
504 /* ARGSUSED */
505 static int
506 termp_ns_pre(DECL_ARGS)
507 {
508
509 p->flags |= TERMP_NOSPACE;
510 return(1);
511 }
512
513
514 /* ARGSUSED */
515 static int
516 termp_pp_pre(DECL_ARGS)
517 {
518
519 vspace(p);
520 return(1);
521 }
522
523
524 /* ARGSUSED */
525 static void
526 termp_ar_post(DECL_ARGS)
527 {
528
529 p->flags &= ~ttypes[TTYPE_CMD_ARG];
530 }
531
532
533 /* ARGSUSED */
534 static int
535 termp_ex_pre(DECL_ARGS)
536 {
537 int i;
538
539 i = arg_getattr(MDOC_Std, node->data.elem.argc,
540 node->data.elem.argv);
541 assert(i >= 0);
542
543 word(p, "The");
544 p->flags |= ttypes[TTYPE_PROG];
545 word(p, *node->data.elem.argv[i].value);
546 p->flags &= ~ttypes[TTYPE_PROG];
547 word(p, "utility exits 0 on success, and >0 if an error occurs.");
548
549 return(1);
550 }
551
552
553 /* ARGSUSED */
554 static int
555 termp_nd_pre(DECL_ARGS)
556 {
557
558 word(p, "\\-");
559 return(1);
560 }
561
562
563 /* ARGSUSED */
564 static void
565 termp_bl_post(DECL_ARGS)
566 {
567
568 if (MDOC_BLOCK == node->type)
569 newln(p);
570 }
571
572
573 /* ARGSUSED */
574 static void
575 termp_op_post(DECL_ARGS)
576 {
577
578 if (MDOC_BODY != node->type)
579 return;
580 p->flags |= TERMP_NOSPACE;
581 word(p, "\\(rB");
582 }
583
584
585 /* ARGSUSED */
586 static void
587 termp_sh_post(DECL_ARGS)
588 {
589
590 switch (node->type) {
591 case (MDOC_HEAD):
592 p->flags &= ~ttypes[TTYPE_SECTION];
593 newln(p);
594 break;
595 case (MDOC_BODY):
596 newln(p);
597 p->offset -= INDENT;
598 break;
599 default:
600 break;
601 }
602 }
603
604
605 /* ARGSUSED */
606 static int
607 termp_xr_pre(DECL_ARGS)
608 {
609 const struct mdoc_node *n;
610
611 n = node->child;
612 assert(n);
613
614 assert(MDOC_TEXT == n->type);
615 word(p, n->data.text.string);
616
617 if (NULL == (n = n->next))
618 return(0);
619
620 assert(MDOC_TEXT == n->type);
621 p->flags |= TERMP_NOSPACE;
622 word(p, "(");
623 p->flags |= TERMP_NOSPACE;
624 word(p, n->data.text.string);
625 p->flags |= TERMP_NOSPACE;
626 word(p, ")");
627
628 return(0);
629 }
630
631
632 /* ARGSUSED */
633 static int
634 termp_vt_pre(DECL_ARGS)
635 {
636
637 /* FIXME: this can be "type name". */
638 p->flags |= ttypes[TTYPE_VAR_DECL];
639 return(1);
640 }
641
642
643 /* ARGSUSED */
644 static void
645 termp_vt_post(DECL_ARGS)
646 {
647
648 p->flags &= ~ttypes[TTYPE_VAR_DECL];
649 if (node->sec == SEC_SYNOPSIS)
650 vspace(p);
651 }
652
653
654 /* ARGSUSED */
655 static int
656 termp_fd_pre(DECL_ARGS)
657 {
658
659 /*
660 * FIXME: this naming is bad. This value is used, in general,
661 * for the #include header or other preprocessor statement.
662 */
663 p->flags |= ttypes[TTYPE_FUNC_DECL];
664 return(1);
665 }
666
667
668 /* ARGSUSED */
669 static void
670 termp_fd_post(DECL_ARGS)
671 {
672
673 p->flags &= ~ttypes[TTYPE_FUNC_DECL];
674 if (node->sec == SEC_SYNOPSIS)
675 vspace(p);
676
677 }
678
679
680 /* ARGSUSED */
681 static int
682 termp_sh_pre(DECL_ARGS)
683 {
684
685 switch (node->type) {
686 case (MDOC_HEAD):
687 vspace(p);
688 p->flags |= ttypes[TTYPE_SECTION];
689 break;
690 case (MDOC_BODY):
691 p->offset += INDENT;
692 break;
693 default:
694 break;
695 }
696 return(1);
697 }
698
699
700 /* ARGSUSED */
701 static int
702 termp_op_pre(DECL_ARGS)
703 {
704
705 switch (node->type) {
706 case (MDOC_BODY):
707 word(p, "\\(lB");
708 p->flags |= TERMP_NOSPACE;
709 break;
710 default:
711 break;
712 }
713 return(1);
714 }
715
716
717 /* ARGSUSED */
718 static int
719 termp_ud_pre(DECL_ARGS)
720 {
721
722 word(p, "currently under development.");
723 return(1);
724 }
725
726
727 /* ARGSUSED */
728 static int
729 termp_fl_pre(DECL_ARGS)
730 {
731
732 p->flags |= ttypes[TTYPE_CMD_FLAG];
733 word(p, "\\-");
734 p->flags |= TERMP_NOSPACE;
735 return(1);
736 }
737
738
739 /* ARGSUSED */
740 static int
741 termp_d1_pre(DECL_ARGS)
742 {
743
744 if (MDOC_BODY != node->type)
745 return(1);
746 newln(p);
747 p->offset += INDENT;
748 return(1);
749 }
750
751
752 /* ARGSUSED */
753 static void
754 termp_d1_post(DECL_ARGS)
755 {
756
757 if (MDOC_BODY != node->type)
758 return;
759 newln(p);
760 p->offset -= INDENT;
761 }
762
763
764 /* ARGSUSED */
765 static int
766 termp_aq_pre(DECL_ARGS)
767 {
768
769 if (MDOC_BODY != node->type)
770 return(1);
771 word(p, "<");
772 p->flags |= TERMP_NOSPACE;
773 return(1);
774 }
775
776
777 /* ARGSUSED */
778 static void
779 termp_aq_post(DECL_ARGS)
780 {
781
782 if (MDOC_BODY != node->type)
783 return;
784 p->flags |= TERMP_NOSPACE;
785 word(p, ">");
786 }
787
788
789 /* ARGSUSED */
790 static int
791 termp_ft_pre(DECL_ARGS)
792 {
793
794 p->flags |= ttypes[TTYPE_FUNC_TYPE];
795 return(1);
796 }
797
798
799 /* ARGSUSED */
800 static void
801 termp_ft_post(DECL_ARGS)
802 {
803
804 p->flags &= ~ttypes[TTYPE_FUNC_TYPE];
805 if (node->sec == SEC_SYNOPSIS)
806 newln(p);
807
808 }
809
810
811 /* ARGSUSED */
812 static int
813 termp_fn_pre(DECL_ARGS)
814 {
815 const struct mdoc_node *n;
816
817 assert(node->child);
818 assert(MDOC_TEXT == node->child->type);
819
820 /* FIXME: can be "type funcname" "type varname"... */
821
822 p->flags |= ttypes[TTYPE_FUNC_NAME];
823 word(p, node->child->data.text.string);
824 p->flags &= ~ttypes[TTYPE_FUNC_NAME];
825
826 p->flags |= TERMP_NOSPACE;
827 word(p, "(");
828
829 p->flags |= TERMP_NOSPACE;
830 for (n = node->child->next; n; n = n->next) {
831 assert(MDOC_TEXT == n->type);
832 p->flags |= ttypes[TTYPE_FUNC_ARG];
833 word(p, n->data.text.string);
834 p->flags &= ~ttypes[TTYPE_FUNC_ARG];
835 if ((n->next))
836 word(p, ",");
837 }
838
839 p->flags |= TERMP_NOSPACE;
840 word(p, ")");
841
842 if (SEC_SYNOPSIS == node->sec)
843 word(p, ";");
844
845 return(0);
846 }
847
848
849 /* ARGSUSED */
850 static void
851 termp_fn_post(DECL_ARGS)
852 {
853
854 if (node->sec == SEC_SYNOPSIS)
855 vspace(p);
856
857 }
858
859
860 /* ARGSUSED */
861 static int
862 termp_sx_pre(DECL_ARGS)
863 {
864
865 p->flags |= ttypes[TTYPE_LINK];
866 return(1);
867 }
868
869
870 /* ARGSUSED */
871 static void
872 termp_sx_post(DECL_ARGS)
873 {
874
875 p->flags &= ~ttypes[TTYPE_LINK];
876 }
877
878
879 /* ARGSUSED */
880 static int
881 termp_fa_pre(DECL_ARGS)
882 {
883
884 p->flags |= ttypes[TTYPE_FUNC_ARG];
885 return(1);
886 }
887
888
889 /* ARGSUSED */
890 static void
891 termp_fa_post(DECL_ARGS)
892 {
893
894 p->flags &= ~ttypes[TTYPE_FUNC_ARG];
895 }
896
897
898 /* ARGSUSED */
899 static int
900 termp_va_pre(DECL_ARGS)
901 {
902
903 p->flags |= ttypes[TTYPE_VAR_DECL];
904 return(1);
905 }
906
907
908 /* ARGSUSED */
909 static void
910 termp_va_post(DECL_ARGS)
911 {
912
913 p->flags &= ~ttypes[TTYPE_VAR_DECL];
914 }
915
916
917 /* ARGSUSED */
918 static int
919 termp_bd_pre(DECL_ARGS)
920 {
921 const struct mdoc_block *bl;
922 const struct mdoc_node *n;
923
924 if (MDOC_BLOCK == node->type) {
925 vspace(p);
926 return(1);
927 } else if (MDOC_BODY != node->type)
928 return(1);
929
930 assert(MDOC_BLOCK == node->parent->type);
931
932 bl = &node->parent->data.block;
933 if ( ! arg_hasattr(MDOC_Literal, bl->argc, bl->argv))
934 return(1);
935
936 p->flags |= TERMP_LITERAL;
937
938 for (n = node->child; n; n = n->next) {
939 assert(MDOC_TEXT == n->type); /* FIXME */
940 if ((*n->data.text.string)) {
941 word(p, n->data.text.string);
942 flushln(p);
943 } else
944 vspace(p);
945
946 }
947
948 p->flags &= ~TERMP_LITERAL;
949 return(0);
950 }
951
952
953 /* ARGSUSED */
954 static int
955 termp_qq_pre(DECL_ARGS)
956 {
957
958 if (MDOC_BODY != node->type)
959 return(1);
960 word(p, "\"");
961 p->flags |= TERMP_NOSPACE;
962 return(1);
963 }
964
965
966 /* ARGSUSED */
967 static void
968 termp_qq_post(DECL_ARGS)
969 {
970
971 if (MDOC_BODY != node->type)
972 return;
973 p->flags |= TERMP_NOSPACE;
974 word(p, "\"");
975 }
976
977
978 /* ARGSUSED */
979 static int
980 termp_ox_pre(DECL_ARGS)
981 {
982
983 word(p, "OpenBSD");
984 return(1);
985 }
986
987
988 /* ARGSUSED */
989 static int
990 termp_nx_pre(DECL_ARGS)
991 {
992
993 word(p, "NetBSD");
994 return(1);
995 }
996
997
998 /* ARGSUSED */
999 static int
1000 termp_sq_pre(DECL_ARGS)
1001 {
1002
1003 if (MDOC_BODY != node->type)
1004 return(1);
1005 word(p, "`");
1006 p->flags |= TERMP_NOSPACE;
1007 return(1);
1008 }
1009
1010
1011 /* ARGSUSED */
1012 static void
1013 termp_sq_post(DECL_ARGS)
1014 {
1015
1016 if (MDOC_BODY != node->type)
1017 return;
1018 p->flags |= TERMP_NOSPACE;
1019 word(p, "\'");
1020 }
1021
1022
1023 /* ARGSUSED */
1024 static int
1025 termp_pf_pre(DECL_ARGS)
1026 {
1027
1028 p->flags |= TERMP_IGNDELIM;
1029 return(1);
1030 }
1031
1032
1033 /* ARGSUSED */
1034 static void
1035 termp_pf_post(DECL_ARGS)
1036 {
1037
1038 p->flags &= ~TERMP_IGNDELIM;
1039 p->flags |= TERMP_NOSPACE;
1040 }
1041
1042