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