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