Annotation of mandoc/term.c, Revision 1.17
1.17 ! kristaps 1: /* $Id: term.c,v 1.16 2009/02/24 16:16:45 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. */
1.12 kristaps 33: /* FIXME: handle nested lists. */
1.10 kristaps 34:
35: #define TTYPE_PROG 0
36: #define TTYPE_CMD_FLAG 1
37: #define TTYPE_CMD_ARG 2
38: #define TTYPE_SECTION 3
39: #define TTYPE_FUNC_DECL 4
40: #define TTYPE_VAR_DECL 5
41: #define TTYPE_FUNC_TYPE 6
42: #define TTYPE_FUNC_NAME 7
43: #define TTYPE_FUNC_ARG 8
44: #define TTYPE_LINK 9
45: #define TTYPE_SSECTION 10
46: #define TTYPE_FILE 11
1.11 kristaps 47: #define TTYPE_EMPH 12
1.14 kristaps 48: #define TTYPE_CONFIG 13
49: #define TTYPE_CMD 14
50: #define TTYPE_INCLUDE 15
1.17 ! kristaps 51: #define TTYPE_SYMB 16
! 52: #define TTYPE_SYMBOL 17
! 53: #define TTYPE_NMAX 18
1.10 kristaps 54:
55: /*
56: * These define "styles" for element types, like command arguments or
57: * executable names. This is useful when multiple macros must decorate
58: * the same thing (like .Ex -std cmd and .Nm cmd).
59: */
60:
61: const int ttypes[TTYPE_NMAX] = {
62: TERMP_BOLD, /* TTYPE_PROG */
63: TERMP_BOLD, /* TTYPE_CMD_FLAG */
64: TERMP_UNDERLINE, /* TTYPE_CMD_ARG */
65: TERMP_BOLD, /* TTYPE_SECTION */
66: TERMP_BOLD, /* TTYPE_FUNC_DECL */
67: TERMP_UNDERLINE, /* TTYPE_VAR_DECL */
68: TERMP_UNDERLINE, /* TTYPE_FUNC_TYPE */
69: TERMP_BOLD, /* TTYPE_FUNC_NAME */
70: TERMP_UNDERLINE, /* TTYPE_FUNC_ARG */
71: TERMP_UNDERLINE, /* TTYPE_LINK */
72: TERMP_BOLD, /* TTYPE_SSECTION */
1.11 kristaps 73: TERMP_UNDERLINE, /* TTYPE_FILE */
1.14 kristaps 74: TERMP_UNDERLINE, /* TTYPE_EMPH */
75: TERMP_BOLD, /* TTYPE_CONFIG */
76: TERMP_BOLD, /* TTYPE_CMD */
1.17 ! kristaps 77: TERMP_BOLD, /* TTYPE_INCLUDE */
! 78: TERMP_BOLD, /* TTYPE_SYMB */
! 79: TERMP_BOLD /* TTYPE_SYMBOL */
1.10 kristaps 80: };
1.7 kristaps 81:
1.10 kristaps 82: static int arg_hasattr(int, size_t,
83: const struct mdoc_arg *);
84: static int arg_getattr(int, size_t,
85: const struct mdoc_arg *);
1.12 kristaps 86: static size_t arg_offset(const struct mdoc_arg *);
87: static size_t arg_width(const struct mdoc_arg *);
1.10 kristaps 88:
89: /*
90: * What follows describes prefix and postfix operations for the abstract
91: * syntax tree descent.
92: */
1.1 kristaps 93:
1.10 kristaps 94: #define DECL_ARGS \
95: struct termp *p, \
96: const struct mdoc_meta *meta, \
97: const struct mdoc_node *node
98:
99: #define DECL_PRE(name) \
100: static int name##_pre(DECL_ARGS)
101: #define DECL_POST(name) \
102: static void name##_post(DECL_ARGS)
103: #define DECL_PREPOST(name) \
104: DECL_PRE(name); \
105: DECL_POST(name);
106:
107: DECL_PREPOST(termp_aq);
108: DECL_PREPOST(termp_ar);
1.17 ! kristaps 109: DECL_PREPOST(termp_bf);
1.12 kristaps 110: DECL_PREPOST(termp_bd);
1.15 kristaps 111: DECL_PREPOST(termp_bq);
1.14 kristaps 112: DECL_PREPOST(termp_cd);
113: DECL_PREPOST(termp_cm);
1.10 kristaps 114: DECL_PREPOST(termp_d1);
115: DECL_PREPOST(termp_dq);
1.11 kristaps 116: DECL_PREPOST(termp_em);
1.10 kristaps 117: DECL_PREPOST(termp_fa);
118: DECL_PREPOST(termp_fd);
119: DECL_PREPOST(termp_fl);
120: DECL_PREPOST(termp_fn);
1.16 kristaps 121: DECL_PREPOST(termp_fo);
1.10 kristaps 122: DECL_PREPOST(termp_ft);
1.14 kristaps 123: DECL_PREPOST(termp_ic);
124: DECL_PREPOST(termp_in);
1.10 kristaps 125: DECL_PREPOST(termp_it);
1.17 ! kristaps 126: DECL_PREPOST(termp_ms);
1.10 kristaps 127: DECL_PREPOST(termp_nm);
128: DECL_PREPOST(termp_op);
129: DECL_PREPOST(termp_pa);
130: DECL_PREPOST(termp_pf);
1.15 kristaps 131: DECL_PREPOST(termp_pq);
1.10 kristaps 132: DECL_PREPOST(termp_qq);
133: DECL_PREPOST(termp_sh);
134: DECL_PREPOST(termp_ss);
135: DECL_PREPOST(termp_sq);
136: DECL_PREPOST(termp_sx);
1.17 ! kristaps 137: DECL_PREPOST(termp_sy);
1.10 kristaps 138: DECL_PREPOST(termp_va);
139: DECL_PREPOST(termp_vt);
140:
1.14 kristaps 141: DECL_PRE(termp_at);
1.15 kristaps 142: DECL_PRE(termp_bsx);
1.17 ! kristaps 143: DECL_PRE(termp_bt);
1.10 kristaps 144: DECL_PRE(termp_bx);
145: DECL_PRE(termp_ex);
1.16 kristaps 146: DECL_PRE(termp_fx);
1.10 kristaps 147: DECL_PRE(termp_nd);
148: DECL_PRE(termp_ns);
149: DECL_PRE(termp_nx);
150: DECL_PRE(termp_ox);
151: DECL_PRE(termp_pp);
1.14 kristaps 152: DECL_PRE(termp_rv);
153: DECL_PRE(termp_st);
1.10 kristaps 154: DECL_PRE(termp_ud);
1.16 kristaps 155: DECL_PRE(termp_ux);
1.10 kristaps 156: DECL_PRE(termp_xr);
157:
158: DECL_POST(termp_bl);
159:
160: const struct termact __termacts[MDOC_MAX] = {
161: { NULL, NULL }, /* \" */
162: { NULL, NULL }, /* Dd */
163: { NULL, NULL }, /* Dt */
164: { NULL, NULL }, /* Os */
165: { termp_sh_pre, termp_sh_post }, /* Sh */
166: { termp_ss_pre, termp_ss_post }, /* Ss */
167: { termp_pp_pre, NULL }, /* Pp */
168: { termp_d1_pre, termp_d1_post }, /* D1 */
169: { NULL, NULL }, /* Dl */
1.12 kristaps 170: { termp_bd_pre, termp_bd_post }, /* Bd */
1.10 kristaps 171: { NULL, NULL }, /* Ed */
172: { NULL, termp_bl_post }, /* Bl */
173: { NULL, NULL }, /* El */
174: { termp_it_pre, termp_it_post }, /* It */
175: { NULL, NULL }, /* Ad */
176: { NULL, NULL }, /* An */
177: { termp_ar_pre, termp_ar_post }, /* Ar */
1.14 kristaps 178: { termp_cd_pre, termp_cd_post }, /* Cd */
179: { termp_cm_pre, termp_cm_post }, /* Cm */
1.10 kristaps 180: { NULL, NULL }, /* Dv */
181: { NULL, NULL }, /* Er */
182: { NULL, NULL }, /* Ev */
183: { termp_ex_pre, NULL }, /* Ex */
184: { termp_fa_pre, termp_fa_post }, /* Fa */
185: { termp_fd_pre, termp_fd_post }, /* Fd */
186: { termp_fl_pre, termp_fl_post }, /* Fl */
187: { termp_fn_pre, termp_fn_post }, /* Fn */
188: { termp_ft_pre, termp_ft_post }, /* Ft */
1.14 kristaps 189: { termp_ic_pre, termp_ic_post }, /* Ic */
190: { termp_in_pre, termp_in_post }, /* In */
1.10 kristaps 191: { NULL, NULL }, /* Li */
192: { termp_nd_pre, NULL }, /* Nd */
193: { termp_nm_pre, termp_nm_post }, /* Nm */
194: { termp_op_pre, termp_op_post }, /* Op */
195: { NULL, NULL }, /* Ot */
196: { termp_pa_pre, termp_pa_post }, /* Pa */
1.14 kristaps 197: { termp_rv_pre, NULL }, /* Rv */
198: { termp_st_pre, NULL }, /* St */
1.10 kristaps 199: { termp_va_pre, termp_va_post }, /* Va */
200: { termp_vt_pre, termp_vt_post }, /* Vt */
201: { termp_xr_pre, NULL }, /* Xr */
202: { NULL, NULL }, /* %A */
203: { NULL, NULL }, /* %B */
204: { NULL, NULL }, /* %D */
205: { NULL, NULL }, /* %I */
206: { NULL, NULL }, /* %J */
207: { NULL, NULL }, /* %N */
208: { NULL, NULL }, /* %O */
209: { NULL, NULL }, /* %P */
210: { NULL, NULL }, /* %R */
211: { NULL, NULL }, /* %T */
212: { NULL, NULL }, /* %V */
213: { NULL, NULL }, /* Ac */
1.14 kristaps 214: { termp_aq_pre, termp_aq_post }, /* Ao */
1.10 kristaps 215: { termp_aq_pre, termp_aq_post }, /* Aq */
1.14 kristaps 216: { termp_at_pre, NULL }, /* At */
1.10 kristaps 217: { NULL, NULL }, /* Bc */
1.17 ! kristaps 218: { termp_bf_pre, termp_bf_post }, /* Bf */
1.15 kristaps 219: { termp_bq_pre, termp_bq_post }, /* Bo */
220: { termp_bq_pre, termp_bq_post }, /* Bq */
221: { termp_bsx_pre, NULL }, /* Bsx */
1.10 kristaps 222: { termp_bx_pre, NULL }, /* Bx */
223: { NULL, NULL }, /* Db */
224: { NULL, NULL }, /* Dc */
1.15 kristaps 225: { termp_dq_pre, termp_dq_post }, /* Do */
1.10 kristaps 226: { termp_dq_pre, termp_dq_post }, /* Dq */
227: { NULL, NULL }, /* Ec */
228: { NULL, NULL }, /* Ef */
1.11 kristaps 229: { termp_em_pre, termp_em_post }, /* Em */
1.10 kristaps 230: { NULL, NULL }, /* Eo */
1.16 kristaps 231: { termp_fx_pre, NULL }, /* Fx */
1.17 ! kristaps 232: { termp_ms_pre, termp_ms_post }, /* Ms */
1.10 kristaps 233: { NULL, NULL }, /* No */
234: { termp_ns_pre, NULL }, /* Ns */
235: { termp_nx_pre, NULL }, /* Nx */
236: { termp_ox_pre, NULL }, /* Ox */
237: { NULL, NULL }, /* Pc */
238: { termp_pf_pre, termp_pf_post }, /* Pf */
1.15 kristaps 239: { termp_pq_pre, termp_pq_post }, /* Po */
240: { termp_pq_pre, termp_pq_post }, /* Pq */
1.10 kristaps 241: { NULL, NULL }, /* Qc */
1.16 kristaps 242: { termp_sq_pre, termp_sq_post }, /* Ql */
1.15 kristaps 243: { termp_qq_pre, termp_qq_post }, /* Qo */
1.10 kristaps 244: { termp_qq_pre, termp_qq_post }, /* Qq */
245: { NULL, NULL }, /* Re */
246: { NULL, NULL }, /* Rs */
247: { NULL, NULL }, /* Sc */
1.15 kristaps 248: { termp_sq_pre, termp_sq_post }, /* So */
1.10 kristaps 249: { termp_sq_pre, termp_sq_post }, /* Sq */
250: { NULL, NULL }, /* Sm */
251: { termp_sx_pre, termp_sx_post }, /* Sx */
1.17 ! kristaps 252: { termp_sy_pre, termp_sy_post }, /* Sy */
1.10 kristaps 253: { NULL, NULL }, /* Tn */
1.16 kristaps 254: { termp_ux_pre, NULL }, /* Ux */
1.10 kristaps 255: { NULL, NULL }, /* Xc */
256: { NULL, NULL }, /* Xo */
1.16 kristaps 257: { termp_fo_pre, termp_fo_post }, /* Fo */
1.10 kristaps 258: { NULL, NULL }, /* Fc */
1.16 kristaps 259: { termp_op_pre, termp_op_post }, /* Oo */
1.10 kristaps 260: { NULL, NULL }, /* Oc */
261: { NULL, NULL }, /* Bk */
262: { NULL, NULL }, /* Ek */
1.17 ! kristaps 263: { termp_bt_pre, NULL }, /* Bt */
1.10 kristaps 264: { NULL, NULL }, /* Hf */
265: { NULL, NULL }, /* Fr */
266: { termp_ud_pre, NULL }, /* Ud */
1.2 kristaps 267: };
268:
1.10 kristaps 269: const struct termact *termacts = __termacts;
270:
271:
272: static size_t
1.12 kristaps 273: arg_width(const struct mdoc_arg *arg)
1.10 kristaps 274: {
1.12 kristaps 275:
276: /* TODO */
277: assert(*arg->value);
278: return(strlen(*arg->value));
279: }
280:
281:
282: static size_t
283: arg_offset(const struct mdoc_arg *arg)
284: {
285:
286: /* TODO */
287: assert(*arg->value);
288: if (0 == strcmp(*arg->value, "indent"))
1.10 kristaps 289: return(INDENT);
1.12 kristaps 290: if (0 == strcmp(*arg->value, "indent-two"))
1.10 kristaps 291: return(INDENT * 2);
292:
1.12 kristaps 293: return(strlen(*arg->value));
1.10 kristaps 294: }
295:
1.3 kristaps 296:
1.10 kristaps 297: static int
298: arg_hasattr(int arg, size_t argc, const struct mdoc_arg *argv)
1.2 kristaps 299: {
300:
1.10 kristaps 301: return(-1 != arg_getattr(arg, argc, argv));
302: }
303:
304:
305: static int
306: arg_getattr(int arg, size_t argc, const struct mdoc_arg *argv)
307: {
308: int i;
309:
310: for (i = 0; i < (int)argc; i++)
311: if (argv[i].arg == arg)
312: return(i);
313: return(-1);
314: }
315:
316:
317: /* ARGSUSED */
318: static int
319: termp_dq_pre(DECL_ARGS)
320: {
321:
322: if (MDOC_BODY != node->type)
323: return(1);
324:
325: word(p, "``");
326: p->flags |= TERMP_NOSPACE;
327: return(1);
328: }
329:
330:
331: /* ARGSUSED */
332: static void
333: termp_dq_post(DECL_ARGS)
334: {
335:
336: if (MDOC_BODY != node->type)
337: return;
1.3 kristaps 338:
1.10 kristaps 339: p->flags |= TERMP_NOSPACE;
340: word(p, "''");
341: }
1.2 kristaps 342:
1.3 kristaps 343:
1.10 kristaps 344: /* ARGSUSED */
345: static void
346: termp_it_post(DECL_ARGS)
347: {
348: const struct mdoc_node *n, *it;
349: const struct mdoc_block *bl;
350: int i;
1.12 kristaps 351: size_t width, offset;
1.2 kristaps 352:
1.8 kristaps 353: /*
1.10 kristaps 354: * This (and termp_it_pre()) are the most complicated functions
355: * here. They must account for a considerable number of
356: * switches that completely change the output behaviour, like
357: * -tag versus -column. Yech.
1.8 kristaps 358: */
1.10 kristaps 359:
360: switch (node->type) {
361: case (MDOC_BODY):
362: /* FALLTHROUGH */
363: case (MDOC_HEAD):
364: break;
365: default:
1.8 kristaps 366: return;
367: }
368:
1.10 kristaps 369: it = node->parent;
370: assert(MDOC_BLOCK == it->type);
371: assert(MDOC_It == it->tok);
372:
373: n = it->parent;
374: assert(MDOC_BODY == n->type);
375: assert(MDOC_Bl == n->tok);
376: n = n->parent;
377: bl = &n->data.block;
378:
379: /* If `-tag', adjust our margins accordingly. */
380:
381: if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
1.12 kristaps 382: flushln(p);
383:
384: /* FIXME: this should auto-size. */
1.10 kristaps 385: i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
1.12 kristaps 386: width = i >= 0 ? arg_width(&bl->argv[i]) : 10;
387:
388: /* FIXME: nesting! Should happen at block. */
389: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
390: offset = i >= 0 ? arg_width(&bl->argv[i]) : 0;
1.10 kristaps 391:
392: if (MDOC_HEAD == node->type) {
393: p->rmargin = p->maxrmargin;
1.12 kristaps 394: p->offset -= offset;
1.10 kristaps 395: p->flags &= ~TERMP_NOBREAK;
396: } else {
1.12 kristaps 397: p->offset -= width;
1.10 kristaps 398: p->flags &= ~TERMP_NOLPAD;
1.2 kristaps 399: }
1.10 kristaps 400: }
1.2 kristaps 401:
1.10 kristaps 402: if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
403: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
1.12 kristaps 404: offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0;
1.3 kristaps 405:
1.10 kristaps 406: flushln(p);
1.12 kristaps 407: p->offset -= offset;
1.10 kristaps 408: return;
1.2 kristaps 409: }
1.10 kristaps 410: }
411:
412:
413: /* ARGSUSED */
414: static int
415: termp_it_pre(DECL_ARGS)
416: {
417: const struct mdoc_node *n, *it;
418: const struct mdoc_block *bl;
419: int i;
1.12 kristaps 420: size_t width, offset;
1.2 kristaps 421:
1.3 kristaps 422: /*
1.10 kristaps 423: * Also see termp_it_post() for general comments.
1.3 kristaps 424: */
425:
1.10 kristaps 426: switch (node->type) {
427: case (MDOC_BODY):
428: /* FALLTHROUGH */
429: case (MDOC_HEAD):
430: it = node->parent;
431: break;
432: case (MDOC_BLOCK):
433: it = node;
434: break;
435: default:
436: return(1);
437: }
438:
439: assert(MDOC_BLOCK == it->type);
440: assert(MDOC_It == it->tok);
441:
442: n = it->parent;
443: assert(MDOC_BODY == n->type);
444: assert(MDOC_Bl == n->tok);
445: n = n->parent;
446: bl = &n->data.block;
447:
448: /* If `-compact', don't assert vertical space. */
449:
450: if (MDOC_BLOCK == node->type) {
451: if (arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
452: newln(p);
453: else
454: vspace(p);
455: return(1);
456: }
457:
458: assert(MDOC_HEAD == node->type
459: || MDOC_BODY == node->type);
460:
1.12 kristaps 461: /* FIXME: see termp_it_post(). */
462:
1.10 kristaps 463: /* If `-tag', adjust our margins accordingly. */
464:
465: if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
1.12 kristaps 466: p->flags |= TERMP_NOSPACE;
467:
1.10 kristaps 468: i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
1.12 kristaps 469: width = i >= 0 ? arg_width(&bl->argv[i]) : 10;
1.10 kristaps 470:
1.12 kristaps 471: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
472: offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0;
1.10 kristaps 473:
474: if (MDOC_HEAD == node->type) {
475: p->flags |= TERMP_NOBREAK;
1.12 kristaps 476: p->offset += offset;
1.10 kristaps 477: p->rmargin = p->offset + width;
478: } else {
479: p->flags |= TERMP_NOSPACE;
480: p->flags |= TERMP_NOLPAD;
1.12 kristaps 481: p->offset += width;
1.10 kristaps 482: }
483: return(1);
484: }
485:
486: /* If `-ohang', adjust left-margin. */
487:
488: if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
489: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
1.12 kristaps 490: offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0;
1.10 kristaps 491:
492: p->flags |= TERMP_NOSPACE;
1.12 kristaps 493: p->offset += offset;
1.10 kristaps 494: return(1);
495: }
1.3 kristaps 496:
1.10 kristaps 497: return(1);
1.2 kristaps 498: }
499:
500:
1.10 kristaps 501: /* ARGSUSED */
502: static void
503: termp_nm_post(DECL_ARGS)
504: {
505:
506: p->flags &= ~ttypes[TTYPE_PROG];
507: }
508:
509:
510: /* ARGSUSED */
511: static void
512: termp_fl_post(DECL_ARGS)
513: {
514:
515: p->flags &= ~ttypes[TTYPE_CMD_FLAG];
516: }
517:
518:
519: /* ARGSUSED */
520: static int
521: termp_ar_pre(DECL_ARGS)
522: {
523:
524: p->flags |= ttypes[TTYPE_CMD_ARG];
525: if (NULL == node->child)
526: word(p, "...");
527: return(1);
528: }
529:
530:
531: /* ARGSUSED */
532: static int
533: termp_nm_pre(DECL_ARGS)
534: {
535:
536: p->flags |= ttypes[TTYPE_PROG];
537: if (NULL == node->child)
538: word(p, meta->name);
539: return(1);
540: }
541:
542:
543: /* ARGSUSED */
544: static int
545: termp_ns_pre(DECL_ARGS)
1.2 kristaps 546: {
547:
548: p->flags |= TERMP_NOSPACE;
1.10 kristaps 549: return(1);
550: }
551:
552:
553: /* ARGSUSED */
554: static int
555: termp_pp_pre(DECL_ARGS)
556: {
557:
558: vspace(p);
559: return(1);
560: }
561:
562:
563: /* ARGSUSED */
564: static void
565: termp_ar_post(DECL_ARGS)
566: {
567:
568: p->flags &= ~ttypes[TTYPE_CMD_ARG];
569: }
570:
571:
572: /* ARGSUSED */
573: static int
1.14 kristaps 574: termp_st_pre(DECL_ARGS)
575: {
576: const char *tp;
577:
578: assert(1 == node->data.elem.argc);
579:
580: tp = mdoc_st2a(node->data.elem.argv[0].arg);
581: word(p, tp);
582:
583: return(1);
584: }
585:
586:
587: /* ARGSUSED */
588: static int
589: termp_rv_pre(DECL_ARGS)
590: {
591: int i;
592:
593: i = arg_getattr(MDOC_Std, node->data.elem.argc,
594: node->data.elem.argv);
595: assert(i >= 0);
596:
597: newln(p);
598: word(p, "The");
599:
600: p->flags |= ttypes[TTYPE_FUNC_NAME];
601: word(p, *node->data.elem.argv[i].value);
602: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
603:
604: word(p, "() function returns the value 0 if successful;");
605: word(p, "otherwise the value -1 is returned and the");
606: word(p, "global variable");
607:
608: p->flags |= ttypes[TTYPE_VAR_DECL];
609: word(p, "errno");
610: p->flags &= ~ttypes[TTYPE_VAR_DECL];
611:
612: word(p, "is set to indicate the error.");
613:
614: return(1);
615: }
616:
617:
618: /* ARGSUSED */
619: static int
1.10 kristaps 620: termp_ex_pre(DECL_ARGS)
621: {
622: int i;
623:
624: i = arg_getattr(MDOC_Std, node->data.elem.argc,
625: node->data.elem.argv);
626: assert(i >= 0);
627:
628: word(p, "The");
629: p->flags |= ttypes[TTYPE_PROG];
630: word(p, *node->data.elem.argv[i].value);
631: p->flags &= ~ttypes[TTYPE_PROG];
632: word(p, "utility exits 0 on success, and >0 if an error occurs.");
633:
634: return(1);
635: }
636:
637:
638: /* ARGSUSED */
639: static int
640: termp_nd_pre(DECL_ARGS)
641: {
642:
643: word(p, "\\-");
644: return(1);
645: }
646:
647:
648: /* ARGSUSED */
649: static void
650: termp_bl_post(DECL_ARGS)
651: {
652:
653: if (MDOC_BLOCK == node->type)
654: newln(p);
655: }
656:
657:
658: /* ARGSUSED */
659: static void
660: termp_op_post(DECL_ARGS)
661: {
662:
663: if (MDOC_BODY != node->type)
1.2 kristaps 664: return;
1.10 kristaps 665: p->flags |= TERMP_NOSPACE;
666: word(p, "\\(rB");
667: }
668:
669:
670: /* ARGSUSED */
671: static void
672: termp_sh_post(DECL_ARGS)
673: {
674:
675: switch (node->type) {
676: case (MDOC_HEAD):
677: p->flags &= ~ttypes[TTYPE_SECTION];
678: newln(p);
679: break;
680: case (MDOC_BODY):
681: newln(p);
682: p->offset = 0;
683: break;
684: default:
685: break;
686: }
687: }
688:
689:
690: /* ARGSUSED */
691: static int
692: termp_xr_pre(DECL_ARGS)
693: {
694: const struct mdoc_node *n;
695:
696: n = node->child;
697: assert(n);
698:
699: assert(MDOC_TEXT == n->type);
700: word(p, n->data.text.string);
701:
702: if (NULL == (n = n->next))
703: return(0);
704:
705: assert(MDOC_TEXT == n->type);
706: p->flags |= TERMP_NOSPACE;
707: word(p, "(");
708: p->flags |= TERMP_NOSPACE;
709: word(p, n->data.text.string);
710: p->flags |= TERMP_NOSPACE;
711: word(p, ")");
712:
713: return(0);
1.2 kristaps 714: }
715:
716:
1.10 kristaps 717: /* ARGSUSED */
718: static int
719: termp_vt_pre(DECL_ARGS)
1.2 kristaps 720: {
721:
1.10 kristaps 722: /* FIXME: this can be "type name". */
723: p->flags |= ttypes[TTYPE_VAR_DECL];
724: return(1);
1.2 kristaps 725: }
726:
727:
1.10 kristaps 728: /* ARGSUSED */
1.2 kristaps 729: static void
1.10 kristaps 730: termp_vt_post(DECL_ARGS)
731: {
732:
733: p->flags &= ~ttypes[TTYPE_VAR_DECL];
734: if (node->sec == SEC_SYNOPSIS)
735: vspace(p);
736: }
737:
738:
739: /* ARGSUSED */
740: static int
741: termp_fd_pre(DECL_ARGS)
1.2 kristaps 742: {
743:
1.10 kristaps 744: /*
745: * FIXME: this naming is bad. This value is used, in general,
746: * for the #include header or other preprocessor statement.
747: */
748: p->flags |= ttypes[TTYPE_FUNC_DECL];
749: return(1);
1.2 kristaps 750: }
751:
752:
1.10 kristaps 753: /* ARGSUSED */
1.2 kristaps 754: static void
1.10 kristaps 755: termp_fd_post(DECL_ARGS)
1.2 kristaps 756: {
757:
1.10 kristaps 758: p->flags &= ~ttypes[TTYPE_FUNC_DECL];
759: if (node->sec == SEC_SYNOPSIS)
760: vspace(p);
761:
762: }
763:
764:
765: /* ARGSUSED */
766: static int
767: termp_sh_pre(DECL_ARGS)
768: {
1.2 kristaps 769:
1.10 kristaps 770: switch (node->type) {
771: case (MDOC_HEAD):
772: vspace(p);
773: p->flags |= ttypes[TTYPE_SECTION];
1.2 kristaps 774: break;
1.10 kristaps 775: case (MDOC_BODY):
776: p->offset = INDENT;
1.2 kristaps 777: break;
1.10 kristaps 778: default:
779: break;
780: }
781: return(1);
782: }
783:
784:
785: /* ARGSUSED */
786: static int
787: termp_op_pre(DECL_ARGS)
788: {
789:
790: switch (node->type) {
791: case (MDOC_BODY):
792: word(p, "\\(lB");
793: p->flags |= TERMP_NOSPACE;
1.2 kristaps 794: break;
795: default:
1.10 kristaps 796: break;
1.2 kristaps 797: }
1.10 kristaps 798: return(1);
799: }
800:
801:
802: /* ARGSUSED */
803: static int
1.17 ! kristaps 804: termp_bt_pre(DECL_ARGS)
! 805: {
! 806:
! 807: word(p, "is currently in beta test.");
! 808: return(1);
! 809: }
! 810:
! 811:
! 812: /* ARGSUSED */
! 813: static int
1.10 kristaps 814: termp_ud_pre(DECL_ARGS)
815: {
816:
817: word(p, "currently under development.");
818: return(1);
819: }
820:
821:
822: /* ARGSUSED */
823: static int
824: termp_fl_pre(DECL_ARGS)
825: {
826:
827: p->flags |= ttypes[TTYPE_CMD_FLAG];
828: word(p, "\\-");
829: p->flags |= TERMP_NOSPACE;
830: return(1);
831: }
832:
833:
834: /* ARGSUSED */
835: static int
836: termp_d1_pre(DECL_ARGS)
837: {
838:
839: if (MDOC_BODY != node->type)
840: return(1);
841: newln(p);
842: p->offset += INDENT;
843: return(1);
1.2 kristaps 844: }
845:
846:
1.10 kristaps 847: /* ARGSUSED */
1.2 kristaps 848: static void
1.10 kristaps 849: termp_d1_post(DECL_ARGS)
850: {
851:
852: if (MDOC_BODY != node->type)
853: return;
854: newln(p);
855: p->offset -= INDENT;
856: }
857:
858:
859: /* ARGSUSED */
860: static int
861: termp_aq_pre(DECL_ARGS)
1.6 kristaps 862: {
863:
1.10 kristaps 864: if (MDOC_BODY != node->type)
865: return(1);
866: word(p, "<");
867: p->flags |= TERMP_NOSPACE;
868: return(1);
869: }
1.6 kristaps 870:
871:
1.10 kristaps 872: /* ARGSUSED */
873: static void
874: termp_aq_post(DECL_ARGS)
875: {
1.6 kristaps 876:
1.10 kristaps 877: if (MDOC_BODY != node->type)
1.6 kristaps 878: return;
1.10 kristaps 879: p->flags |= TERMP_NOSPACE;
880: word(p, ">");
881: }
1.6 kristaps 882:
1.10 kristaps 883:
884: /* ARGSUSED */
885: static int
886: termp_ft_pre(DECL_ARGS)
887: {
888:
889: p->flags |= ttypes[TTYPE_FUNC_TYPE];
890: return(1);
1.6 kristaps 891: }
892:
893:
1.10 kristaps 894: /* ARGSUSED */
1.6 kristaps 895: static void
1.10 kristaps 896: termp_ft_post(DECL_ARGS)
1.2 kristaps 897: {
898:
1.10 kristaps 899: p->flags &= ~ttypes[TTYPE_FUNC_TYPE];
900: if (node->sec == SEC_SYNOPSIS)
901: newln(p);
902:
903: }
1.2 kristaps 904:
905:
1.10 kristaps 906: /* ARGSUSED */
907: static int
908: termp_fn_pre(DECL_ARGS)
909: {
910: const struct mdoc_node *n;
911:
912: assert(node->child);
913: assert(MDOC_TEXT == node->child->type);
1.2 kristaps 914:
1.10 kristaps 915: /* FIXME: can be "type funcname" "type varname"... */
1.2 kristaps 916:
1.10 kristaps 917: p->flags |= ttypes[TTYPE_FUNC_NAME];
918: word(p, node->child->data.text.string);
919: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
920:
921: word(p, "(");
922:
923: p->flags |= TERMP_NOSPACE;
924: for (n = node->child->next; n; n = n->next) {
925: assert(MDOC_TEXT == n->type);
926: p->flags |= ttypes[TTYPE_FUNC_ARG];
927: word(p, n->data.text.string);
928: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1.16 kristaps 929: if (n->next)
1.10 kristaps 930: word(p, ",");
1.6 kristaps 931: }
1.2 kristaps 932:
1.10 kristaps 933: word(p, ")");
934:
935: if (SEC_SYNOPSIS == node->sec)
936: word(p, ";");
937:
938: return(0);
1.2 kristaps 939: }
940:
941:
1.10 kristaps 942: /* ARGSUSED */
943: static void
944: termp_fn_post(DECL_ARGS)
1.2 kristaps 945: {
946:
1.10 kristaps 947: if (node->sec == SEC_SYNOPSIS)
948: vspace(p);
949:
950: }
1.2 kristaps 951:
952:
1.10 kristaps 953: /* ARGSUSED */
954: static int
955: termp_sx_pre(DECL_ARGS)
956: {
1.8 kristaps 957:
1.10 kristaps 958: p->flags |= ttypes[TTYPE_LINK];
959: return(1);
1.2 kristaps 960: }
961:
962:
1.10 kristaps 963: /* ARGSUSED */
1.1 kristaps 964: static void
1.10 kristaps 965: termp_sx_post(DECL_ARGS)
1.2 kristaps 966: {
967:
1.10 kristaps 968: p->flags &= ~ttypes[TTYPE_LINK];
969: }
1.2 kristaps 970:
1.4 kristaps 971:
1.10 kristaps 972: /* ARGSUSED */
973: static int
974: termp_fa_pre(DECL_ARGS)
975: {
1.16 kristaps 976: struct mdoc_node *n;
977:
978: if (node->parent->tok != MDOC_Fo) {
979: p->flags |= ttypes[TTYPE_FUNC_ARG];
980: return(1);
981: }
982:
983: for (n = node->child; n; n = n->next) {
984: assert(MDOC_TEXT == n->type);
985:
986: p->flags |= ttypes[TTYPE_FUNC_ARG];
987: word(p, n->data.text.string);
988: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
989:
990: if (n->next)
991: word(p, ",");
992: }
993:
994: if (node->next && node->next->tok == MDOC_Fa)
995: word(p, ",");
1.2 kristaps 996:
1.16 kristaps 997: return(0);
1.10 kristaps 998: }
1.2 kristaps 999:
1000:
1.10 kristaps 1001: /* ARGSUSED */
1002: static void
1003: termp_fa_post(DECL_ARGS)
1004: {
1005:
1006: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1007: }
1.2 kristaps 1008:
1009:
1.10 kristaps 1010: /* ARGSUSED */
1011: static int
1012: termp_va_pre(DECL_ARGS)
1013: {
1.2 kristaps 1014:
1.10 kristaps 1015: p->flags |= ttypes[TTYPE_VAR_DECL];
1016: return(1);
1.2 kristaps 1017: }
1018:
1019:
1.10 kristaps 1020: /* ARGSUSED */
1.2 kristaps 1021: static void
1.10 kristaps 1022: termp_va_post(DECL_ARGS)
1.1 kristaps 1023: {
1024:
1.10 kristaps 1025: p->flags &= ~ttypes[TTYPE_VAR_DECL];
1026: }
1.1 kristaps 1027:
1.7 kristaps 1028:
1.10 kristaps 1029: /* ARGSUSED */
1030: static int
1031: termp_bd_pre(DECL_ARGS)
1032: {
1033: const struct mdoc_block *bl;
1034: const struct mdoc_node *n;
1.12 kristaps 1035: int i;
1.1 kristaps 1036:
1.10 kristaps 1037: if (MDOC_BLOCK == node->type) {
1038: vspace(p);
1039: return(1);
1040: } else if (MDOC_BODY != node->type)
1041: return(1);
1042:
1043: assert(MDOC_BLOCK == node->parent->type);
1044:
1045: bl = &node->parent->data.block;
1.12 kristaps 1046:
1047: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
1048: if (-1 != i) {
1049: assert(1 == bl->argv[i].sz);
1050: p->offset += arg_offset(&bl->argv[i]);
1051: }
1052:
1.10 kristaps 1053: if ( ! arg_hasattr(MDOC_Literal, bl->argc, bl->argv))
1054: return(1);
1055:
1056: p->flags |= TERMP_LITERAL;
1057:
1058: for (n = node->child; n; n = n->next) {
1059: assert(MDOC_TEXT == n->type); /* FIXME */
1060: if ((*n->data.text.string)) {
1061: word(p, n->data.text.string);
1062: flushln(p);
1063: } else
1064: vspace(p);
1.1 kristaps 1065:
1.10 kristaps 1066: }
1.1 kristaps 1067:
1.10 kristaps 1068: p->flags &= ~TERMP_LITERAL;
1069: return(0);
1070: }
1.1 kristaps 1071:
1072:
1.10 kristaps 1073: /* ARGSUSED */
1.12 kristaps 1074: static void
1075: termp_bd_post(DECL_ARGS)
1076: {
1077: int i;
1078: const struct mdoc_block *bl;
1079:
1080: if (MDOC_BODY != node->type)
1081: return;
1082:
1083: assert(MDOC_BLOCK == node->parent->type);
1084: bl = &node->parent->data.block;
1085:
1086: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
1087: if (-1 != i) {
1088: assert(1 == bl->argv[i].sz);
1089: p->offset -= arg_offset(&bl->argv[i]);
1090: }
1091: }
1092:
1093:
1094: /* ARGSUSED */
1.10 kristaps 1095: static int
1096: termp_qq_pre(DECL_ARGS)
1097: {
1.1 kristaps 1098:
1.10 kristaps 1099: if (MDOC_BODY != node->type)
1100: return(1);
1101: word(p, "\"");
1102: p->flags |= TERMP_NOSPACE;
1103: return(1);
1.1 kristaps 1104: }
1105:
1106:
1.10 kristaps 1107: /* ARGSUSED */
1.1 kristaps 1108: static void
1.10 kristaps 1109: termp_qq_post(DECL_ARGS)
1.1 kristaps 1110: {
1111:
1.10 kristaps 1112: if (MDOC_BODY != node->type)
1113: return;
1114: p->flags |= TERMP_NOSPACE;
1115: word(p, "\"");
1116: }
1117:
1118:
1119: /* ARGSUSED */
1120: static int
1.15 kristaps 1121: termp_bsx_pre(DECL_ARGS)
1122: {
1123:
1124: word(p, "BSDI BSD/OS");
1125: return(1);
1126: }
1127:
1128:
1129: /* ARGSUSED */
1130: static int
1.10 kristaps 1131: termp_bx_pre(DECL_ARGS)
1132: {
1.1 kristaps 1133:
1.10 kristaps 1134: word(p, "BSD");
1135: return(1);
1136: }
1137:
1138:
1139: /* ARGSUSED */
1140: static int
1141: termp_ox_pre(DECL_ARGS)
1142: {
1143:
1144: word(p, "OpenBSD");
1145: return(1);
1146: }
1147:
1148:
1149: /* ARGSUSED */
1150: static int
1.16 kristaps 1151: termp_ux_pre(DECL_ARGS)
1152: {
1153:
1154: word(p, "UNIX");
1155: return(1);
1156: }
1157:
1158:
1159: /* ARGSUSED */
1160: static int
1161: termp_fx_pre(DECL_ARGS)
1162: {
1163:
1164: word(p, "FreeBSD");
1165: return(1);
1166: }
1167:
1168:
1169: /* ARGSUSED */
1170: static int
1.10 kristaps 1171: termp_nx_pre(DECL_ARGS)
1172: {
1173:
1174: word(p, "NetBSD");
1175: return(1);
1176: }
1177:
1178:
1179: /* ARGSUSED */
1180: static int
1181: termp_sq_pre(DECL_ARGS)
1182: {
1183:
1184: if (MDOC_BODY != node->type)
1185: return(1);
1.13 kristaps 1186: word(p, "\'");
1.10 kristaps 1187: p->flags |= TERMP_NOSPACE;
1188: return(1);
1189: }
1.1 kristaps 1190:
1191:
1.10 kristaps 1192: /* ARGSUSED */
1193: static void
1194: termp_sq_post(DECL_ARGS)
1195: {
1196:
1197: if (MDOC_BODY != node->type)
1198: return;
1199: p->flags |= TERMP_NOSPACE;
1200: word(p, "\'");
1201: }
1.2 kristaps 1202:
1203:
1.10 kristaps 1204: /* ARGSUSED */
1205: static int
1206: termp_pf_pre(DECL_ARGS)
1207: {
1.1 kristaps 1208:
1.10 kristaps 1209: p->flags |= TERMP_IGNDELIM;
1210: return(1);
1211: }
1.1 kristaps 1212:
1213:
1.10 kristaps 1214: /* ARGSUSED */
1215: static void
1216: termp_pf_post(DECL_ARGS)
1217: {
1.1 kristaps 1218:
1.10 kristaps 1219: p->flags &= ~TERMP_IGNDELIM;
1220: p->flags |= TERMP_NOSPACE;
1221: }
1.1 kristaps 1222:
1223:
1.10 kristaps 1224: /* ARGSUSED */
1225: static int
1226: termp_ss_pre(DECL_ARGS)
1227: {
1.1 kristaps 1228:
1.10 kristaps 1229: switch (node->type) {
1230: case (MDOC_HEAD):
1231: vspace(p);
1232: p->flags |= ttypes[TTYPE_SSECTION];
1233: p->offset = INDENT / 2;
1234: break;
1235: default:
1236: break;
1237: }
1.1 kristaps 1238:
1.10 kristaps 1239: return(1);
1.1 kristaps 1240: }
1241:
1242:
1.10 kristaps 1243: /* ARGSUSED */
1244: static void
1245: termp_ss_post(DECL_ARGS)
1.1 kristaps 1246: {
1247:
1.10 kristaps 1248: switch (node->type) {
1249: case (MDOC_HEAD):
1250: p->flags &= ~ttypes[TTYPE_SSECTION];
1251: newln(p);
1252: p->offset = INDENT;
1253: break;
1254: default:
1255: break;
1256: }
1257: }
1.2 kristaps 1258:
1259:
1.10 kristaps 1260: /* ARGSUSED */
1261: static int
1262: termp_pa_pre(DECL_ARGS)
1263: {
1.2 kristaps 1264:
1.10 kristaps 1265: p->flags |= ttypes[TTYPE_FILE];
1266: return(1);
1.1 kristaps 1267: }
1268:
1269:
1.10 kristaps 1270: /* ARGSUSED */
1271: static void
1272: termp_pa_post(DECL_ARGS)
1273: {
1274:
1275: p->flags &= ~ttypes[TTYPE_FILE];
1276: }
1.11 kristaps 1277:
1278:
1279: /* ARGSUSED */
1280: static int
1281: termp_em_pre(DECL_ARGS)
1282: {
1283:
1284: p->flags |= ttypes[TTYPE_EMPH];
1285: return(1);
1286: }
1287:
1288:
1289: /* ARGSUSED */
1290: static void
1291: termp_em_post(DECL_ARGS)
1292: {
1293:
1294: p->flags &= ~ttypes[TTYPE_EMPH];
1295: }
1.14 kristaps 1296:
1297:
1298: /* ARGSUSED */
1299: static int
1300: termp_cd_pre(DECL_ARGS)
1301: {
1302:
1303: p->flags |= ttypes[TTYPE_CONFIG];
1304: return(1);
1305: }
1306:
1307:
1308: /* ARGSUSED */
1309: static void
1310: termp_cd_post(DECL_ARGS)
1311: {
1312:
1313: p->flags &= ~ttypes[TTYPE_CONFIG];
1314: }
1315:
1316:
1317: /* ARGSUSED */
1318: static int
1319: termp_cm_pre(DECL_ARGS)
1320: {
1321:
1322: p->flags |= ttypes[TTYPE_CMD_FLAG];
1323: return(1);
1324: }
1325:
1326:
1327: /* ARGSUSED */
1328: static void
1329: termp_cm_post(DECL_ARGS)
1330: {
1331:
1332: p->flags &= ~ttypes[TTYPE_CMD_FLAG];
1333: }
1334:
1335:
1336: /* ARGSUSED */
1337: static int
1338: termp_ic_pre(DECL_ARGS)
1339: {
1340:
1341: p->flags |= ttypes[TTYPE_CMD];
1342: return(1);
1343: }
1344:
1345:
1346: /* ARGSUSED */
1347: static void
1348: termp_ic_post(DECL_ARGS)
1349: {
1350:
1351: p->flags &= ~ttypes[TTYPE_CMD];
1352: }
1353:
1354:
1355: /* ARGSUSED */
1356: static int
1357: termp_in_pre(DECL_ARGS)
1358: {
1359:
1360: p->flags |= ttypes[TTYPE_INCLUDE];
1361: return(1);
1362: }
1363:
1364:
1365: /* ARGSUSED */
1366: static void
1367: termp_in_post(DECL_ARGS)
1368: {
1369:
1370: p->flags &= ~ttypes[TTYPE_INCLUDE];
1371: }
1372:
1373:
1374: /* ARGSUSED */
1375: static int
1376: termp_at_pre(DECL_ARGS)
1377: {
1378: enum mdoc_att c;
1379:
1380: c = ATT_DEFAULT;
1381: if (node->child) {
1382: assert(MDOC_TEXT == node->child->type);
1383: c = mdoc_atoatt(node->child->data.text.string);
1384: }
1385:
1386: word(p, mdoc_att2a(c));
1387: return(0);
1388: }
1.15 kristaps 1389:
1390:
1391: /* ARGSUSED */
1392: static int
1393: termp_bq_pre(DECL_ARGS)
1394: {
1395:
1396: if (MDOC_BODY != node->type)
1397: return(1);
1398: word(p, "[");
1399: p->flags |= TERMP_NOSPACE;
1400: return(1);
1401: }
1402:
1403:
1404: /* ARGSUSED */
1405: static void
1406: termp_bq_post(DECL_ARGS)
1407: {
1408:
1409: if (MDOC_BODY != node->type)
1410: return;
1411: word(p, "]");
1412: }
1413:
1414:
1415: /* ARGSUSED */
1416: static int
1417: termp_pq_pre(DECL_ARGS)
1418: {
1419:
1420: if (MDOC_BODY != node->type)
1421: return(1);
1422: word(p, "(");
1423: p->flags |= TERMP_NOSPACE;
1424: return(1);
1425: }
1426:
1427:
1428: /* ARGSUSED */
1429: static void
1430: termp_pq_post(DECL_ARGS)
1431: {
1432:
1433: if (MDOC_BODY != node->type)
1434: return;
1435: word(p, ")");
1436: }
1437:
1438:
1.16 kristaps 1439: /* ARGSUSED */
1440: static int
1441: termp_fo_pre(DECL_ARGS)
1442: {
1443: const struct mdoc_node *n;
1444:
1445: if (MDOC_BODY == node->type) {
1446: word(p, "(");
1447: p->flags |= TERMP_NOSPACE;
1448: return(1);
1449: } else if (MDOC_HEAD != node->type)
1450: return(1);
1451:
1.17 ! kristaps 1452: /* XXX - groff shows only first parameter */
! 1453:
1.16 kristaps 1454: p->flags |= ttypes[TTYPE_FUNC_NAME];
1455: for (n = node->child; n; n = n->next) {
1456: assert(MDOC_TEXT == n->type);
1457: word(p, n->data.text.string);
1458: }
1459: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
1460:
1461: return(0);
1462: }
1463:
1464:
1465: /* ARGSUSED */
1466: static void
1467: termp_fo_post(DECL_ARGS)
1468: {
1469:
1470: if (MDOC_BODY != node->type)
1471: return;
1472: word(p, ")");
1473: word(p, ";");
1474: newln(p);
1475: }
1476:
1477:
1.17 ! kristaps 1478: /* ARGSUSED */
! 1479: static int
! 1480: termp_bf_pre(DECL_ARGS)
! 1481: {
! 1482: const struct mdoc_node *n;
! 1483: const struct mdoc_block *b;
! 1484:
! 1485: /* XXX - we skip over possible trailing HEAD tokens. */
! 1486:
! 1487: if (MDOC_HEAD == node->type)
! 1488: return(0);
! 1489: else if (MDOC_BLOCK != node->type)
! 1490: return(1);
! 1491:
! 1492: b = &node->data.block;
! 1493:
! 1494: if (NULL == (n = b->head->child)) {
! 1495: if (arg_hasattr(MDOC_Emphasis, b->argc, b->argv))
! 1496: p->flags |= ttypes[TTYPE_EMPH];
! 1497: else if (arg_hasattr(MDOC_Symbolic, b->argc, b->argv))
! 1498: p->flags |= ttypes[TTYPE_SYMB];
! 1499:
! 1500: return(1);
! 1501: }
! 1502:
! 1503: assert(MDOC_TEXT == n->type);
! 1504:
! 1505: if (0 == strcmp("Em", n->data.text.string))
! 1506: p->flags |= ttypes[TTYPE_EMPH];
! 1507: else if (0 == strcmp("Sy", n->data.text.string))
! 1508: p->flags |= ttypes[TTYPE_SYMB];
! 1509:
! 1510: return(1);
! 1511: }
! 1512:
! 1513:
! 1514: /* ARGSUSED */
! 1515: static void
! 1516: termp_bf_post(DECL_ARGS)
! 1517: {
! 1518: const struct mdoc_node *n;
! 1519: const struct mdoc_block *b;
! 1520:
! 1521: if (MDOC_BLOCK != node->type)
! 1522: return;
! 1523:
! 1524: b = &node->data.block;
! 1525:
! 1526: if (NULL == (n = b->head->child)) {
! 1527: if (arg_hasattr(MDOC_Emphasis, b->argc, b->argv))
! 1528: p->flags &= ~ttypes[TTYPE_EMPH];
! 1529: else if (arg_hasattr(MDOC_Symbolic, b->argc, b->argv))
! 1530: p->flags &= ~ttypes[TTYPE_SYMB];
! 1531:
! 1532: return;
! 1533: }
! 1534:
! 1535: assert(MDOC_TEXT == n->type);
! 1536:
! 1537: if (0 == strcmp("Emphasis", n->data.text.string))
! 1538: p->flags &= ~ttypes[TTYPE_EMPH];
! 1539: else if (0 == strcmp("Symbolic", n->data.text.string))
! 1540: p->flags &= ~ttypes[TTYPE_SYMB];
! 1541:
! 1542: return;
! 1543: }
! 1544:
! 1545:
! 1546: /* ARGSUSED */
! 1547: static int
! 1548: termp_sy_pre(DECL_ARGS)
! 1549: {
! 1550:
! 1551: p->flags |= ttypes[TTYPE_SYMB];
! 1552: return(1);
! 1553: }
! 1554:
! 1555:
! 1556: /* ARGSUSED */
! 1557: static void
! 1558: termp_sy_post(DECL_ARGS)
! 1559: {
! 1560:
! 1561: p->flags &= ~ttypes[TTYPE_SYMB];
! 1562: }
! 1563:
! 1564:
! 1565: /* ARGSUSED */
! 1566: static int
! 1567: termp_ms_pre(DECL_ARGS)
! 1568: {
! 1569:
! 1570: p->flags |= ttypes[TTYPE_SYMBOL];
! 1571: return(1);
! 1572: }
! 1573:
! 1574:
! 1575: /* ARGSUSED */
! 1576: static void
! 1577: termp_ms_post(DECL_ARGS)
! 1578: {
! 1579:
! 1580: p->flags &= ~ttypes[TTYPE_SYMBOL];
! 1581: }
CVSweb