Annotation of mandoc/termact.c, Revision 1.6
1.6 ! kristaps 1: /* $Id: termact.c,v 1.5 2009/02/22 15:50:45 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);
1.5 kristaps 86: DECL_PRE(termp_bd);
1.1 kristaps 87: DECL_PRE(termp_d1);
88: DECL_PRE(termp_dq);
89: DECL_PRE(termp_ex);
1.4 kristaps 90: DECL_PRE(termp_fa);
91: DECL_PRE(termp_fd);
1.1 kristaps 92: DECL_PRE(termp_fl);
1.4 kristaps 93: DECL_PRE(termp_fn);
94: DECL_PRE(termp_ft);
1.1 kristaps 95: DECL_PRE(termp_it);
96: DECL_PRE(termp_nd);
97: DECL_PRE(termp_nm);
98: DECL_PRE(termp_ns);
1.6 ! kristaps 99: DECL_PRE(termp_nx);
1.1 kristaps 100: DECL_PRE(termp_op);
1.6 ! kristaps 101: DECL_PRE(termp_ox);
! 102: DECL_PRE(termp_pf);
1.1 kristaps 103: DECL_PRE(termp_pp);
1.5 kristaps 104: DECL_PRE(termp_qq);
1.1 kristaps 105: DECL_PRE(termp_sh);
1.6 ! kristaps 106: DECL_PRE(termp_sq);
1.4 kristaps 107: DECL_PRE(termp_sx);
1.1 kristaps 108: DECL_PRE(termp_ud);
1.5 kristaps 109: DECL_PRE(termp_va);
1.4 kristaps 110: DECL_PRE(termp_vt);
1.1 kristaps 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);
1.4 kristaps 118: DECL_POST(termp_fa);
119: DECL_POST(termp_fd);
1.1 kristaps 120: DECL_POST(termp_fl);
1.4 kristaps 121: DECL_POST(termp_fn);
122: DECL_POST(termp_ft);
1.1 kristaps 123: DECL_POST(termp_it);
124: DECL_POST(termp_nm);
125: DECL_POST(termp_op);
1.6 ! kristaps 126: DECL_POST(termp_pf);
1.5 kristaps 127: DECL_POST(termp_qq);
1.1 kristaps 128: DECL_POST(termp_sh);
1.6 ! kristaps 129: DECL_POST(termp_sq);
1.4 kristaps 130: DECL_POST(termp_sx);
1.5 kristaps 131: DECL_POST(termp_va);
1.4 kristaps 132: DECL_POST(termp_vt);
1.1 kristaps 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 */
1.5 kristaps 144: { termp_bd_pre, NULL }, /* Bd */
1.1 kristaps 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 */
1.4 kristaps 158: { termp_fa_pre, termp_fa_post }, /* Fa */
159: { termp_fd_pre, termp_fd_post }, /* Fd */
1.1 kristaps 160: { termp_fl_pre, termp_fl_post }, /* Fl */
1.4 kristaps 161: { termp_fn_pre, termp_fn_post }, /* Fn */
162: { termp_ft_pre, termp_ft_post }, /* Ft */
1.1 kristaps 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 */
1.5 kristaps 173: { termp_va_pre, termp_va_post }, /* Va */
1.4 kristaps 174: { termp_vt_pre, termp_vt_post }, /* Vt */
1.1 kristaps 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 */
1.6 ! kristaps 209: { termp_nx_pre, NULL }, /* Nx */
! 210: { termp_ox_pre, NULL }, /* Ox */
1.1 kristaps 211: { NULL, NULL }, /* Pc */
1.6 ! kristaps 212: { termp_pf_pre, termp_pf_post }, /* Pf */
1.1 kristaps 213: { NULL, NULL }, /* Po */
214: { NULL, NULL }, /* Pq */
215: { NULL, NULL }, /* Qc */
216: { NULL, NULL }, /* Ql */
217: { NULL, NULL }, /* Qo */
1.5 kristaps 218: { termp_qq_pre, termp_qq_post }, /* Qq */
1.1 kristaps 219: { NULL, NULL }, /* Re */
220: { NULL, NULL }, /* Rs */
221: { NULL, NULL }, /* Sc */
222: { NULL, NULL }, /* So */
1.6 ! kristaps 223: { termp_sq_pre, termp_sq_post }, /* Sq */
1.1 kristaps 224: { NULL, NULL }, /* Sm */
1.4 kristaps 225: { termp_sx_pre, termp_sx_post }, /* Sx */
1.1 kristaps 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:
1.4 kristaps 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:
1.1 kristaps 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 */
1.2 kristaps 294: static void
1.1 kristaps 295: termp_dq_post(DECL_ARGS)
296: {
297:
298: if (MDOC_BODY != node->type)
1.2 kristaps 299: return;
1.1 kristaps 300:
301: p->flags |= TERMP_NOSPACE;
302: word(p, "''");
303: }
304:
305:
306: /* ARGSUSED */
1.2 kristaps 307: static void
1.1 kristaps 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:
1.2 kristaps 328: return;
1.1 kristaps 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: }
1.4 kristaps 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;
1.1 kristaps 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: }
1.4 kristaps 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);
1.1 kristaps 456: }
457:
458: return(1);
459: }
460:
461:
462: /* ARGSUSED */
1.2 kristaps 463: static void
1.1 kristaps 464: termp_nm_post(DECL_ARGS)
465: {
466:
467: p->flags &= ~ttypes[TTYPE_PROG];
468: }
469:
470:
471: /* ARGSUSED */
1.2 kristaps 472: static void
1.1 kristaps 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 */
1.2 kristaps 525: static void
1.1 kristaps 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 */
1.2 kristaps 564: static void
1.1 kristaps 565: termp_bl_post(DECL_ARGS)
566: {
567:
1.2 kristaps 568: if (MDOC_BLOCK == node->type)
1.1 kristaps 569: newln(p);
570: }
571:
572:
573: /* ARGSUSED */
1.2 kristaps 574: static void
1.1 kristaps 575: termp_op_post(DECL_ARGS)
576: {
577:
1.2 kristaps 578: if (MDOC_BODY != node->type)
579: return;
580: p->flags |= TERMP_NOSPACE;
581: word(p, "\\(rB");
1.1 kristaps 582: }
583:
584:
585: /* ARGSUSED */
1.2 kristaps 586: static void
1.1 kristaps 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);
1.4 kristaps 597: p->offset -= INDENT;
1.1 kristaps 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;
1.2 kristaps 622: word(p, "(");
1.1 kristaps 623: p->flags |= TERMP_NOSPACE;
624: word(p, n->data.text.string);
625: p->flags |= TERMP_NOSPACE;
1.2 kristaps 626: word(p, ")");
1.1 kristaps 627:
628: return(0);
629: }
630:
631:
632: /* ARGSUSED */
633: static int
1.4 kristaps 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
1.1 kristaps 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):
1.4 kristaps 691: p->offset += INDENT;
1.1 kristaps 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):
1.2 kristaps 707: word(p, "\\(lB");
1.1 kristaps 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);
1.4 kristaps 747: p->offset += INDENT;
1.1 kristaps 748: return(1);
749: }
750:
751:
752: /* ARGSUSED */
1.2 kristaps 753: static void
1.1 kristaps 754: termp_d1_post(DECL_ARGS)
755: {
756:
1.2 kristaps 757: if (MDOC_BODY != node->type)
758: return;
1.1 kristaps 759: newln(p);
1.4 kristaps 760: p->offset -= INDENT;
1.1 kristaps 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);
1.3 kristaps 771: word(p, "<");
1.1 kristaps 772: p->flags |= TERMP_NOSPACE;
773: return(1);
774: }
775:
776:
777: /* ARGSUSED */
1.2 kristaps 778: static void
1.1 kristaps 779: termp_aq_post(DECL_ARGS)
780: {
781:
782: if (MDOC_BODY != node->type)
1.2 kristaps 783: return;
1.1 kristaps 784: p->flags |= TERMP_NOSPACE;
1.3 kristaps 785: word(p, ">");
1.1 kristaps 786: }
787:
788:
1.4 kristaps 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 */
1.1 kristaps 812: static int
1.4 kristaps 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)
1.1 kristaps 873: {
874:
1.4 kristaps 875: p->flags &= ~ttypes[TTYPE_LINK];
1.1 kristaps 876: }
877:
878:
1.4 kristaps 879: /* ARGSUSED */
1.1 kristaps 880: static int
1.4 kristaps 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)
1.1 kristaps 892: {
893:
1.4 kristaps 894: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1.1 kristaps 895: }
896:
1.4 kristaps 897:
1.5 kristaps 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:
1.6 ! kristaps 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:
CVSweb