Annotation of mandoc/termact.c, Revision 1.4
1.4 ! kristaps 1: /* $Id: termact.c,v 1.3 2009/02/22 11:23:19 kristaps Exp $ */
1.1 kristaps 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:
1.4 ! kristaps 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:
1.1 kristaps 32: #define TTYPE_PROG 0
33: #define TTYPE_CMD_FLAG 1
34: #define TTYPE_CMD_ARG 2
35: #define TTYPE_SECTION 3
1.4 ! kristaps 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
1.1 kristaps 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 */
1.4 ! kristaps 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 */
1.1 kristaps 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 *);
1.4 ! kristaps 67: static size_t arg_offset(const char *);
1.1 kristaps 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:
1.2 kristaps 79: #define DECL_PRE(name) \
80: static int name##_pre(DECL_ARGS)
81: #define DECL_POST(name) \
82: static void name##_post(DECL_ARGS)
1.1 kristaps 83:
84: DECL_PRE(termp_aq);
85: DECL_PRE(termp_ar);
86: DECL_PRE(termp_d1);
87: DECL_PRE(termp_dq);
88: DECL_PRE(termp_ex);
1.4 ! kristaps 89: DECL_PRE(termp_fa);
! 90: DECL_PRE(termp_fd);
1.1 kristaps 91: DECL_PRE(termp_fl);
1.4 ! kristaps 92: DECL_PRE(termp_fn);
! 93: DECL_PRE(termp_ft);
1.1 kristaps 94: DECL_PRE(termp_it);
95: DECL_PRE(termp_nd);
96: DECL_PRE(termp_nm);
97: DECL_PRE(termp_ns);
98: DECL_PRE(termp_op);
99: DECL_PRE(termp_pp);
100: DECL_PRE(termp_sh);
1.4 ! kristaps 101: DECL_PRE(termp_sx);
1.1 kristaps 102: DECL_PRE(termp_ud);
1.4 ! kristaps 103: DECL_PRE(termp_vt);
1.1 kristaps 104: DECL_PRE(termp_xr);
105:
106: DECL_POST(termp_aq);
107: DECL_POST(termp_ar);
108: DECL_POST(termp_bl);
109: DECL_POST(termp_d1);
110: DECL_POST(termp_dq);
1.4 ! kristaps 111: DECL_POST(termp_fa);
! 112: DECL_POST(termp_fd);
1.1 kristaps 113: DECL_POST(termp_fl);
1.4 ! kristaps 114: DECL_POST(termp_fn);
! 115: DECL_POST(termp_ft);
1.1 kristaps 116: DECL_POST(termp_it);
117: DECL_POST(termp_nm);
118: DECL_POST(termp_op);
119: DECL_POST(termp_sh);
1.4 ! kristaps 120: DECL_POST(termp_sx);
! 121: DECL_POST(termp_vt);
1.1 kristaps 122:
123: const struct termact __termacts[MDOC_MAX] = {
124: { NULL, NULL }, /* \" */
125: { NULL, NULL }, /* Dd */
126: { NULL, NULL }, /* Dt */
127: { NULL, NULL }, /* Os */
128: { termp_sh_pre, termp_sh_post }, /* Sh */
129: { NULL, NULL }, /* Ss */
130: { termp_pp_pre, NULL }, /* Pp */
131: { termp_d1_pre, termp_d1_post }, /* D1 */
132: { NULL, NULL }, /* Dl */
133: { NULL, NULL }, /* Bd */
134: { NULL, NULL }, /* Ed */
135: { NULL, termp_bl_post }, /* Bl */
136: { NULL, NULL }, /* El */
137: { termp_it_pre, termp_it_post }, /* It */
138: { NULL, NULL }, /* Ad */
139: { NULL, NULL }, /* An */
140: { termp_ar_pre, termp_ar_post }, /* Ar */
141: { NULL, NULL }, /* Cd */
142: { NULL, NULL }, /* Cm */
143: { NULL, NULL }, /* Dv */
144: { NULL, NULL }, /* Er */
145: { NULL, NULL }, /* Ev */
146: { termp_ex_pre, NULL }, /* Ex */
1.4 ! kristaps 147: { termp_fa_pre, termp_fa_post }, /* Fa */
! 148: { termp_fd_pre, termp_fd_post }, /* Fd */
1.1 kristaps 149: { termp_fl_pre, termp_fl_post }, /* Fl */
1.4 ! kristaps 150: { termp_fn_pre, termp_fn_post }, /* Fn */
! 151: { termp_ft_pre, termp_ft_post }, /* Ft */
1.1 kristaps 152: { NULL, NULL }, /* Ic */
153: { NULL, NULL }, /* In */
154: { NULL, NULL }, /* Li */
155: { termp_nd_pre, NULL }, /* Nd */
156: { termp_nm_pre, termp_nm_post }, /* Nm */
157: { termp_op_pre, termp_op_post }, /* Op */
158: { NULL, NULL }, /* Ot */
159: { NULL, NULL }, /* Pa */
160: { NULL, NULL }, /* Rv */
161: { NULL, NULL }, /* St */
162: { NULL, NULL }, /* Va */
1.4 ! kristaps 163: { termp_vt_pre, termp_vt_post }, /* Vt */
1.1 kristaps 164: { termp_xr_pre, NULL }, /* Xr */
165: { NULL, NULL }, /* %A */
166: { NULL, NULL }, /* %B */
167: { NULL, NULL }, /* %D */
168: { NULL, NULL }, /* %I */
169: { NULL, NULL }, /* %J */
170: { NULL, NULL }, /* %N */
171: { NULL, NULL }, /* %O */
172: { NULL, NULL }, /* %P */
173: { NULL, NULL }, /* %R */
174: { NULL, NULL }, /* %T */
175: { NULL, NULL }, /* %V */
176: { NULL, NULL }, /* Ac */
177: { NULL, NULL }, /* Ao */
178: { termp_aq_pre, termp_aq_post }, /* Aq */
179: { NULL, NULL }, /* At */
180: { NULL, NULL }, /* Bc */
181: { NULL, NULL }, /* Bf */
182: { NULL, NULL }, /* Bo */
183: { NULL, NULL }, /* Bq */
184: { NULL, NULL }, /* Bsx */
185: { NULL, NULL }, /* Bx */
186: { NULL, NULL }, /* Db */
187: { NULL, NULL }, /* Dc */
188: { NULL, NULL }, /* Do */
189: { termp_dq_pre, termp_dq_post }, /* Dq */
190: { NULL, NULL }, /* Ec */
191: { NULL, NULL }, /* Ef */
192: { NULL, NULL }, /* Em */
193: { NULL, NULL }, /* Eo */
194: { NULL, NULL }, /* Fx */
195: { NULL, NULL }, /* Ms */
196: { NULL, NULL }, /* No */
197: { termp_ns_pre, NULL }, /* Ns */
198: { NULL, NULL }, /* Nx */
199: { NULL, NULL }, /* Ox */
200: { NULL, NULL }, /* Pc */
201: { NULL, NULL }, /* Pf */
202: { NULL, NULL }, /* Po */
203: { NULL, NULL }, /* Pq */
204: { NULL, NULL }, /* Qc */
205: { NULL, NULL }, /* Ql */
206: { NULL, NULL }, /* Qo */
207: { NULL, NULL }, /* Qq */
208: { NULL, NULL }, /* Re */
209: { NULL, NULL }, /* Rs */
210: { NULL, NULL }, /* Sc */
211: { NULL, NULL }, /* So */
212: { NULL, NULL }, /* Sq */
213: { NULL, NULL }, /* Sm */
1.4 ! kristaps 214: { termp_sx_pre, termp_sx_post }, /* Sx */
1.1 kristaps 215: { NULL, NULL }, /* Sy */
216: { NULL, NULL }, /* Tn */
217: { NULL, NULL }, /* Ux */
218: { NULL, NULL }, /* Xc */
219: { NULL, NULL }, /* Xo */
220: { NULL, NULL }, /* Fo */
221: { NULL, NULL }, /* Fc */
222: { NULL, NULL }, /* Oo */
223: { NULL, NULL }, /* Oc */
224: { NULL, NULL }, /* Bk */
225: { NULL, NULL }, /* Ek */
226: { NULL, NULL }, /* Bt */
227: { NULL, NULL }, /* Hf */
228: { NULL, NULL }, /* Fr */
229: { termp_ud_pre, NULL }, /* Ud */
230: };
231:
232: const struct termact *termacts = __termacts;
233:
234:
1.4 ! kristaps 235: static size_t
! 236: arg_offset(const char *v)
! 237: {
! 238: if (0 == strcmp(v, "indent"))
! 239: return(INDENT);
! 240: if (0 == strcmp(v, "indent-two"))
! 241: return(INDENT * 2);
! 242:
! 243: /* TODO */
! 244: return(0);
! 245: }
! 246:
! 247:
! 248: static int
! 249: arg_hasattr(int arg, size_t argc, const struct mdoc_arg *argv)
! 250: {
! 251:
! 252: return(-1 != arg_getattr(arg, argc, argv));
! 253: }
! 254:
! 255:
! 256: static int
! 257: arg_getattr(int arg, size_t argc, const struct mdoc_arg *argv)
! 258: {
! 259: int i;
! 260:
! 261: for (i = 0; i < (int)argc; i++)
! 262: if (argv[i].arg == arg)
! 263: return(i);
! 264: return(-1);
! 265: }
! 266:
! 267:
1.1 kristaps 268: /* ARGSUSED */
269: static int
270: termp_dq_pre(DECL_ARGS)
271: {
272:
273: if (MDOC_BODY != node->type)
274: return(1);
275:
276: word(p, "``");
277: p->flags |= TERMP_NOSPACE;
278: return(1);
279: }
280:
281:
282: /* ARGSUSED */
1.2 kristaps 283: static void
1.1 kristaps 284: termp_dq_post(DECL_ARGS)
285: {
286:
287: if (MDOC_BODY != node->type)
1.2 kristaps 288: return;
1.1 kristaps 289:
290: p->flags |= TERMP_NOSPACE;
291: word(p, "''");
292: }
293:
294:
295: /* ARGSUSED */
1.2 kristaps 296: static void
1.1 kristaps 297: termp_it_post(DECL_ARGS)
298: {
299: const struct mdoc_node *n, *it;
300: const struct mdoc_block *bl;
301: int i;
302: size_t width;
303:
304: /*
305: * This (and termp_it_pre()) are the most complicated functions
306: * here. They must account for a considerable number of
307: * switches that completely change the output behaviour, like
308: * -tag versus -column. Yech.
309: */
310:
311: switch (node->type) {
312: case (MDOC_BODY):
313: /* FALLTHROUGH */
314: case (MDOC_HEAD):
315: break;
316: default:
1.2 kristaps 317: return;
1.1 kristaps 318: }
319:
320: it = node->parent;
321: assert(MDOC_BLOCK == it->type);
322: assert(MDOC_It == it->tok);
323:
324: n = it->parent;
325: assert(MDOC_BODY == n->type);
326: assert(MDOC_Bl == n->tok);
327: n = n->parent;
328: bl = &n->data.block;
329:
330: /* If `-tag', adjust our margins accordingly. */
331:
332: if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
333: i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
334: assert(i >= 0);
335: assert(1 == bl->argv[i].sz);
336: width = strlen(*bl->argv[i].value); /* XXX */
337:
338: if (MDOC_HEAD == node->type) {
339: flushln(p);
340: /* FIXME: nested lists. */
341: p->rmargin = p->maxrmargin;
342: p->flags &= ~TERMP_NOBREAK;
343: } else {
344: flushln(p);
345: p->offset -= width + 1;
346: p->flags &= ~TERMP_NOLPAD;
347: }
1.4 ! kristaps 348: return;
! 349: }
! 350:
! 351: if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
! 352: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
! 353: assert(i >= 0);
! 354: assert(1 == bl->argv[i].sz);
! 355: width = arg_offset(*bl->argv[i].value);
! 356:
! 357: flushln(p);
! 358: p->offset -= width + 1;
! 359: return;
1.1 kristaps 360: }
361: }
362:
363:
364: /* ARGSUSED */
365: static int
366: termp_it_pre(DECL_ARGS)
367: {
368: const struct mdoc_node *n, *it;
369: const struct mdoc_block *bl;
370: int i;
371: size_t width;
372:
373: /*
374: * Also see termp_it_post() for general comments.
375: */
376:
377: switch (node->type) {
378: case (MDOC_BODY):
379: /* FALLTHROUGH */
380: case (MDOC_HEAD):
381: it = node->parent;
382: break;
383: case (MDOC_BLOCK):
384: it = node;
385: break;
386: default:
387: return(1);
388: }
389:
390: assert(MDOC_BLOCK == it->type);
391: assert(MDOC_It == it->tok);
392:
393: n = it->parent;
394: assert(MDOC_BODY == n->type);
395: assert(MDOC_Bl == n->tok);
396: n = n->parent;
397: bl = &n->data.block;
398:
399: /* If `-compact', don't assert vertical space. */
400:
401: if (MDOC_BLOCK == node->type) {
402: if (arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
403: newln(p);
404: else
405: vspace(p);
406: return(1);
407: }
408:
409: assert(MDOC_HEAD == node->type
410: || MDOC_BODY == node->type);
411:
412: /* If `-tag', adjust our margins accordingly. */
413:
414: if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
415: i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
416: assert(i >= 0); /* XXX */
417: assert(1 == bl->argv[i].sz);
418: width = strlen(*bl->argv[i].value); /* XXX */
419:
420: /* FIXME: nested lists. */
421:
422: if (MDOC_HEAD == node->type) {
423: p->flags |= TERMP_NOBREAK;
424: p->flags |= TERMP_NOSPACE;
425: p->rmargin = p->offset + width;
426: } else {
427: p->flags |= TERMP_NOSPACE;
428: p->flags |= TERMP_NOLPAD;
429: p->offset += width + 1;
430: }
1.4 ! kristaps 431: return(1);
! 432: }
! 433:
! 434: /* If `-ohang', adjust left-margin. */
! 435:
! 436: if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
! 437: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
! 438: assert(i >= 0);
! 439: assert(1 == bl->argv[i].sz);
! 440: width = arg_offset(*bl->argv[i].value);
! 441:
! 442: p->flags |= TERMP_NOSPACE;
! 443: p->offset += width + 1;
! 444: return(1);
1.1 kristaps 445: }
446:
447: return(1);
448: }
449:
450:
451: /* ARGSUSED */
1.2 kristaps 452: static void
1.1 kristaps 453: termp_nm_post(DECL_ARGS)
454: {
455:
456: p->flags &= ~ttypes[TTYPE_PROG];
457: }
458:
459:
460: /* ARGSUSED */
1.2 kristaps 461: static void
1.1 kristaps 462: termp_fl_post(DECL_ARGS)
463: {
464:
465: p->flags &= ~ttypes[TTYPE_CMD_FLAG];
466: }
467:
468:
469: /* ARGSUSED */
470: static int
471: termp_ar_pre(DECL_ARGS)
472: {
473:
474: p->flags |= ttypes[TTYPE_CMD_ARG];
475: if (NULL == node->child)
476: word(p, "...");
477: return(1);
478: }
479:
480:
481: /* ARGSUSED */
482: static int
483: termp_nm_pre(DECL_ARGS)
484: {
485:
486: p->flags |= ttypes[TTYPE_PROG];
487: if (NULL == node->child)
488: word(p, meta->name);
489: return(1);
490: }
491:
492:
493: /* ARGSUSED */
494: static int
495: termp_ns_pre(DECL_ARGS)
496: {
497:
498: p->flags |= TERMP_NOSPACE;
499: return(1);
500: }
501:
502:
503: /* ARGSUSED */
504: static int
505: termp_pp_pre(DECL_ARGS)
506: {
507:
508: vspace(p);
509: return(1);
510: }
511:
512:
513: /* ARGSUSED */
1.2 kristaps 514: static void
1.1 kristaps 515: termp_ar_post(DECL_ARGS)
516: {
517:
518: p->flags &= ~ttypes[TTYPE_CMD_ARG];
519: }
520:
521:
522: /* ARGSUSED */
523: static int
524: termp_ex_pre(DECL_ARGS)
525: {
526: int i;
527:
528: i = arg_getattr(MDOC_Std, node->data.elem.argc,
529: node->data.elem.argv);
530: assert(i >= 0);
531:
532: word(p, "The");
533: p->flags |= ttypes[TTYPE_PROG];
534: word(p, *node->data.elem.argv[i].value);
535: p->flags &= ~ttypes[TTYPE_PROG];
536: word(p, "utility exits 0 on success, and >0 if an error occurs.");
537:
538: return(1);
539: }
540:
541:
542: /* ARGSUSED */
543: static int
544: termp_nd_pre(DECL_ARGS)
545: {
546:
547: word(p, "\\-");
548: return(1);
549: }
550:
551:
552: /* ARGSUSED */
1.2 kristaps 553: static void
1.1 kristaps 554: termp_bl_post(DECL_ARGS)
555: {
556:
1.2 kristaps 557: if (MDOC_BLOCK == node->type)
1.1 kristaps 558: newln(p);
559: }
560:
561:
562: /* ARGSUSED */
1.2 kristaps 563: static void
1.1 kristaps 564: termp_op_post(DECL_ARGS)
565: {
566:
1.2 kristaps 567: if (MDOC_BODY != node->type)
568: return;
569: p->flags |= TERMP_NOSPACE;
570: word(p, "\\(rB");
1.1 kristaps 571: }
572:
573:
574: /* ARGSUSED */
1.2 kristaps 575: static void
1.1 kristaps 576: termp_sh_post(DECL_ARGS)
577: {
578:
579: switch (node->type) {
580: case (MDOC_HEAD):
581: p->flags &= ~ttypes[TTYPE_SECTION];
582: newln(p);
583: break;
584: case (MDOC_BODY):
585: newln(p);
1.4 ! kristaps 586: p->offset -= INDENT;
1.1 kristaps 587: break;
588: default:
589: break;
590: }
591: }
592:
593:
594: /* ARGSUSED */
595: static int
596: termp_xr_pre(DECL_ARGS)
597: {
598: const struct mdoc_node *n;
599:
600: n = node->child;
601: assert(n);
602:
603: assert(MDOC_TEXT == n->type);
604: word(p, n->data.text.string);
605:
606: if (NULL == (n = n->next))
607: return(0);
608:
609: assert(MDOC_TEXT == n->type);
610: p->flags |= TERMP_NOSPACE;
1.2 kristaps 611: word(p, "(");
1.1 kristaps 612: p->flags |= TERMP_NOSPACE;
613: word(p, n->data.text.string);
614: p->flags |= TERMP_NOSPACE;
1.2 kristaps 615: word(p, ")");
1.1 kristaps 616:
617: return(0);
618: }
619:
620:
621: /* ARGSUSED */
622: static int
1.4 ! kristaps 623: termp_vt_pre(DECL_ARGS)
! 624: {
! 625:
! 626: /* FIXME: this can be "type name". */
! 627: p->flags |= ttypes[TTYPE_VAR_DECL];
! 628: return(1);
! 629: }
! 630:
! 631:
! 632: /* ARGSUSED */
! 633: static void
! 634: termp_vt_post(DECL_ARGS)
! 635: {
! 636:
! 637: p->flags &= ~ttypes[TTYPE_VAR_DECL];
! 638: if (node->sec == SEC_SYNOPSIS)
! 639: vspace(p);
! 640: }
! 641:
! 642:
! 643: /* ARGSUSED */
! 644: static int
! 645: termp_fd_pre(DECL_ARGS)
! 646: {
! 647:
! 648: /*
! 649: * FIXME: this naming is bad. This value is used, in general,
! 650: * for the #include header or other preprocessor statement.
! 651: */
! 652: p->flags |= ttypes[TTYPE_FUNC_DECL];
! 653: return(1);
! 654: }
! 655:
! 656:
! 657: /* ARGSUSED */
! 658: static void
! 659: termp_fd_post(DECL_ARGS)
! 660: {
! 661:
! 662: p->flags &= ~ttypes[TTYPE_FUNC_DECL];
! 663: if (node->sec == SEC_SYNOPSIS)
! 664: vspace(p);
! 665:
! 666: }
! 667:
! 668:
! 669: /* ARGSUSED */
! 670: static int
1.1 kristaps 671: termp_sh_pre(DECL_ARGS)
672: {
673:
674: switch (node->type) {
675: case (MDOC_HEAD):
676: vspace(p);
677: p->flags |= ttypes[TTYPE_SECTION];
678: break;
679: case (MDOC_BODY):
1.4 ! kristaps 680: p->offset += INDENT;
1.1 kristaps 681: break;
682: default:
683: break;
684: }
685: return(1);
686: }
687:
688:
689: /* ARGSUSED */
690: static int
691: termp_op_pre(DECL_ARGS)
692: {
693:
694: switch (node->type) {
695: case (MDOC_BODY):
1.2 kristaps 696: word(p, "\\(lB");
1.1 kristaps 697: p->flags |= TERMP_NOSPACE;
698: break;
699: default:
700: break;
701: }
702: return(1);
703: }
704:
705:
706: /* ARGSUSED */
707: static int
708: termp_ud_pre(DECL_ARGS)
709: {
710:
711: word(p, "currently under development.");
712: return(1);
713: }
714:
715:
716: /* ARGSUSED */
717: static int
718: termp_fl_pre(DECL_ARGS)
719: {
720:
721: p->flags |= ttypes[TTYPE_CMD_FLAG];
722: word(p, "\\-");
723: p->flags |= TERMP_NOSPACE;
724: return(1);
725: }
726:
727:
728: /* ARGSUSED */
729: static int
730: termp_d1_pre(DECL_ARGS)
731: {
732:
733: if (MDOC_BODY != node->type)
734: return(1);
735: newln(p);
1.4 ! kristaps 736: p->offset += INDENT;
1.1 kristaps 737: return(1);
738: }
739:
740:
741: /* ARGSUSED */
1.2 kristaps 742: static void
1.1 kristaps 743: termp_d1_post(DECL_ARGS)
744: {
745:
1.2 kristaps 746: if (MDOC_BODY != node->type)
747: return;
1.1 kristaps 748: newln(p);
1.4 ! kristaps 749: p->offset -= INDENT;
1.1 kristaps 750: }
751:
752:
753: /* ARGSUSED */
754: static int
755: termp_aq_pre(DECL_ARGS)
756: {
757:
758: if (MDOC_BODY != node->type)
759: return(1);
1.3 kristaps 760: word(p, "<");
1.1 kristaps 761: p->flags |= TERMP_NOSPACE;
762: return(1);
763: }
764:
765:
766: /* ARGSUSED */
1.2 kristaps 767: static void
1.1 kristaps 768: termp_aq_post(DECL_ARGS)
769: {
770:
771: if (MDOC_BODY != node->type)
1.2 kristaps 772: return;
1.1 kristaps 773: p->flags |= TERMP_NOSPACE;
1.3 kristaps 774: word(p, ">");
1.1 kristaps 775: }
776:
777:
1.4 ! kristaps 778: /* ARGSUSED */
! 779: static int
! 780: termp_ft_pre(DECL_ARGS)
! 781: {
! 782:
! 783: p->flags |= ttypes[TTYPE_FUNC_TYPE];
! 784: return(1);
! 785: }
! 786:
! 787:
! 788: /* ARGSUSED */
! 789: static void
! 790: termp_ft_post(DECL_ARGS)
! 791: {
! 792:
! 793: p->flags &= ~ttypes[TTYPE_FUNC_TYPE];
! 794: if (node->sec == SEC_SYNOPSIS)
! 795: newln(p);
! 796:
! 797: }
! 798:
! 799:
! 800: /* ARGSUSED */
1.1 kristaps 801: static int
1.4 ! kristaps 802: termp_fn_pre(DECL_ARGS)
! 803: {
! 804: const struct mdoc_node *n;
! 805:
! 806: assert(node->child);
! 807: assert(MDOC_TEXT == node->child->type);
! 808:
! 809: /* FIXME: can be "type funcname" "type varname"... */
! 810:
! 811: p->flags |= ttypes[TTYPE_FUNC_NAME];
! 812: word(p, node->child->data.text.string);
! 813: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
! 814:
! 815: p->flags |= TERMP_NOSPACE;
! 816: word(p, "(");
! 817:
! 818: p->flags |= TERMP_NOSPACE;
! 819: for (n = node->child->next; n; n = n->next) {
! 820: assert(MDOC_TEXT == n->type);
! 821: p->flags |= ttypes[TTYPE_FUNC_ARG];
! 822: word(p, n->data.text.string);
! 823: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
! 824: if ((n->next))
! 825: word(p, ",");
! 826: }
! 827:
! 828: p->flags |= TERMP_NOSPACE;
! 829: word(p, ")");
! 830:
! 831: if (SEC_SYNOPSIS == node->sec)
! 832: word(p, ";");
! 833:
! 834: return(0);
! 835: }
! 836:
! 837:
! 838: /* ARGSUSED */
! 839: static void
! 840: termp_fn_post(DECL_ARGS)
! 841: {
! 842:
! 843: if (node->sec == SEC_SYNOPSIS)
! 844: vspace(p);
! 845:
! 846: }
! 847:
! 848:
! 849: /* ARGSUSED */
! 850: static int
! 851: termp_sx_pre(DECL_ARGS)
! 852: {
! 853:
! 854: p->flags |= ttypes[TTYPE_LINK];
! 855: return(1);
! 856: }
! 857:
! 858:
! 859: /* ARGSUSED */
! 860: static void
! 861: termp_sx_post(DECL_ARGS)
1.1 kristaps 862: {
863:
1.4 ! kristaps 864: p->flags &= ~ttypes[TTYPE_LINK];
1.1 kristaps 865: }
866:
867:
1.4 ! kristaps 868: /* ARGSUSED */
1.1 kristaps 869: static int
1.4 ! kristaps 870: termp_fa_pre(DECL_ARGS)
! 871: {
! 872:
! 873: p->flags |= ttypes[TTYPE_FUNC_ARG];
! 874: return(1);
! 875: }
! 876:
! 877:
! 878: /* ARGSUSED */
! 879: static void
! 880: termp_fa_post(DECL_ARGS)
1.1 kristaps 881: {
882:
1.4 ! kristaps 883: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1.1 kristaps 884: }
885:
1.4 ! kristaps 886:
CVSweb