Annotation of mandoc/term.c, Revision 1.30
1.30 ! kristaps 1: /* $Id: term.c,v 1.29 2009/02/28 20:13:06 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.29 kristaps 28: #define INDENT 6
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);
1.30 ! kristaps 121: DECL_PREPOST(termp_in);
1.10 kristaps 122: DECL_PREPOST(termp_it);
123: DECL_PREPOST(termp_op);
124: DECL_PREPOST(termp_pf);
1.15 kristaps 125: DECL_PREPOST(termp_pq);
1.10 kristaps 126: DECL_PREPOST(termp_qq);
127: DECL_PREPOST(termp_sh);
128: DECL_PREPOST(termp_ss);
129: DECL_PREPOST(termp_sq);
130: DECL_PREPOST(termp_vt);
131:
1.18 kristaps 132: DECL_PRE(termp_ar);
1.14 kristaps 133: DECL_PRE(termp_at);
1.18 kristaps 134: DECL_PRE(termp_bf);
1.15 kristaps 135: DECL_PRE(termp_bsx);
1.17 kristaps 136: DECL_PRE(termp_bt);
1.10 kristaps 137: DECL_PRE(termp_bx);
1.18 kristaps 138: DECL_PRE(termp_cd);
139: DECL_PRE(termp_cm);
140: DECL_PRE(termp_em);
1.10 kristaps 141: DECL_PRE(termp_ex);
1.18 kristaps 142: DECL_PRE(termp_fa);
143: DECL_PRE(termp_fl);
1.16 kristaps 144: DECL_PRE(termp_fx);
1.18 kristaps 145: DECL_PRE(termp_ic);
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 */
1.29 kristaps 177: { termp_d1_pre, termp_d1_post }, /* 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 */
1.30 ! kristaps 198: { termp_in_pre, termp_in_post }, /* 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.29 kristaps 211: { NULL, termp____post }, /* %B */
1.28 kristaps 212: { NULL, termp____post }, /* %D */
1.29 kristaps 213: { NULL, termp____post }, /* %I */
1.28 kristaps 214: { NULL, termp____post }, /* %J */
1.29 kristaps 215: { NULL, termp____post }, /* %N */
216: { NULL, termp____post }, /* %O */
217: { NULL, termp____post }, /* %P */
218: { NULL, termp____post }, /* %R */
1.28 kristaps 219: { termp__t_pre, termp__t_post }, /* %T */
1.29 kristaps 220: { NULL, termp____post }, /* %V */
1.10 kristaps 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.29 kristaps 306: return(strlen(*arg->value) + 2);
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) {
1.29 kristaps 398: newln(p);
399: if ( ! arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
400: if (node->prev || n->prev)
401: vspace(p);
1.20 kristaps 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.29 kristaps 566: if (SEC_SYNOPSIS == node->sec)
567: newln(p);
568:
1.18 kristaps 569: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_PROG]);
570: if (NULL == node->child)
571: word(p, meta->name);
572: return(1);
1.10 kristaps 573: }
574:
575:
576: /* ARGSUSED */
1.18 kristaps 577: static int
578: termp_fl_pre(DECL_ARGS)
1.10 kristaps 579: {
580:
1.18 kristaps 581: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_FLAG]);
582: word(p, "\\-");
583: p->flags |= TERMP_NOSPACE;
584: return(1);
1.10 kristaps 585: }
586:
587:
588: /* ARGSUSED */
589: static int
590: termp_ar_pre(DECL_ARGS)
591: {
592:
1.29 kristaps 593: if (node->child) {
594: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_ARG]);
595: return(1);
596: }
597: p->flags |= ttypes[TTYPE_CMD_ARG];
598: word(p, "file");
599: word(p, "...");
600: p->flags &= ~ttypes[TTYPE_CMD_ARG];
1.10 kristaps 601: return(1);
602: }
603:
604:
605: /* ARGSUSED */
606: static int
607: termp_ns_pre(DECL_ARGS)
1.2 kristaps 608: {
609:
610: p->flags |= TERMP_NOSPACE;
1.10 kristaps 611: return(1);
612: }
613:
614:
615: /* ARGSUSED */
616: static int
617: termp_pp_pre(DECL_ARGS)
618: {
619:
620: vspace(p);
621: return(1);
622: }
623:
624:
625: /* ARGSUSED */
626: static int
1.14 kristaps 627: termp_st_pre(DECL_ARGS)
628: {
629: const char *tp;
630:
631: assert(1 == node->data.elem.argc);
632:
633: tp = mdoc_st2a(node->data.elem.argv[0].arg);
634: word(p, tp);
635:
636: return(1);
637: }
638:
639:
640: /* ARGSUSED */
641: static int
1.28 kristaps 642: termp_rs_pre(DECL_ARGS)
643: {
644:
1.30 ! kristaps 645: if (MDOC_BLOCK == node->type && node->prev)
1.28 kristaps 646: vspace(p);
647: return(1);
648: }
649:
650:
651: /* ARGSUSED */
652: static int
1.14 kristaps 653: termp_rv_pre(DECL_ARGS)
654: {
655: int i;
656:
657: i = arg_getattr(MDOC_Std, node->data.elem.argc,
658: node->data.elem.argv);
659: assert(i >= 0);
660:
661: newln(p);
662: word(p, "The");
663:
664: p->flags |= ttypes[TTYPE_FUNC_NAME];
665: word(p, *node->data.elem.argv[i].value);
666: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
667:
668: word(p, "() function returns the value 0 if successful;");
669: word(p, "otherwise the value -1 is returned and the");
670: word(p, "global variable");
671:
672: p->flags |= ttypes[TTYPE_VAR_DECL];
673: word(p, "errno");
674: p->flags &= ~ttypes[TTYPE_VAR_DECL];
675:
676: word(p, "is set to indicate the error.");
677:
678: return(1);
679: }
680:
681:
682: /* ARGSUSED */
683: static int
1.10 kristaps 684: termp_ex_pre(DECL_ARGS)
685: {
686: int i;
687:
688: i = arg_getattr(MDOC_Std, node->data.elem.argc,
689: node->data.elem.argv);
690: assert(i >= 0);
691:
692: word(p, "The");
693: p->flags |= ttypes[TTYPE_PROG];
694: word(p, *node->data.elem.argv[i].value);
695: p->flags &= ~ttypes[TTYPE_PROG];
696: word(p, "utility exits 0 on success, and >0 if an error occurs.");
697:
698: return(1);
699: }
700:
701:
702: /* ARGSUSED */
703: static int
704: termp_nd_pre(DECL_ARGS)
705: {
706:
707: word(p, "\\-");
708: return(1);
709: }
710:
711:
712: /* ARGSUSED */
713: static void
714: termp_bl_post(DECL_ARGS)
715: {
716:
717: if (MDOC_BLOCK == node->type)
718: newln(p);
719: }
720:
721:
722: /* ARGSUSED */
723: static void
724: termp_op_post(DECL_ARGS)
725: {
726:
727: if (MDOC_BODY != node->type)
1.2 kristaps 728: return;
1.10 kristaps 729: p->flags |= TERMP_NOSPACE;
730: word(p, "\\(rB");
731: }
732:
733:
734: /* ARGSUSED */
735: static int
736: termp_xr_pre(DECL_ARGS)
737: {
738: const struct mdoc_node *n;
739:
740: n = node->child;
741: assert(n);
742:
743: assert(MDOC_TEXT == n->type);
744: word(p, n->data.text.string);
745:
746: if (NULL == (n = n->next))
747: return(0);
748:
749: assert(MDOC_TEXT == n->type);
750: p->flags |= TERMP_NOSPACE;
751: word(p, "(");
752: p->flags |= TERMP_NOSPACE;
753: word(p, n->data.text.string);
754: p->flags |= TERMP_NOSPACE;
755: word(p, ")");
756:
757: return(0);
1.2 kristaps 758: }
759:
760:
1.10 kristaps 761: /* ARGSUSED */
762: static int
763: termp_vt_pre(DECL_ARGS)
1.2 kristaps 764: {
765:
1.10 kristaps 766: /* FIXME: this can be "type name". */
1.18 kristaps 767: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 768: return(1);
1.2 kristaps 769: }
770:
771:
1.10 kristaps 772: /* ARGSUSED */
1.2 kristaps 773: static void
1.10 kristaps 774: termp_vt_post(DECL_ARGS)
775: {
776:
777: if (node->sec == SEC_SYNOPSIS)
778: vspace(p);
779: }
780:
781:
782: /* ARGSUSED */
783: static int
784: termp_fd_pre(DECL_ARGS)
1.2 kristaps 785: {
786:
1.10 kristaps 787: /*
788: * FIXME: this naming is bad. This value is used, in general,
789: * for the #include header or other preprocessor statement.
790: */
1.18 kristaps 791: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_DECL]);
1.10 kristaps 792: return(1);
1.2 kristaps 793: }
794:
795:
1.10 kristaps 796: /* ARGSUSED */
1.2 kristaps 797: static void
1.10 kristaps 798: termp_fd_post(DECL_ARGS)
1.2 kristaps 799: {
800:
1.30 ! kristaps 801: if (node->sec != SEC_SYNOPSIS)
! 802: return;
! 803: newln(p);
! 804: if (node->next && MDOC_Fd != node->next->tok)
1.10 kristaps 805: vspace(p);
806: }
807:
808:
809: /* ARGSUSED */
810: static int
811: termp_sh_pre(DECL_ARGS)
812: {
1.2 kristaps 813:
1.10 kristaps 814: switch (node->type) {
815: case (MDOC_HEAD):
816: vspace(p);
1.18 kristaps 817: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SECTION]);
1.2 kristaps 818: break;
1.10 kristaps 819: case (MDOC_BODY):
820: p->offset = INDENT;
1.2 kristaps 821: break;
1.10 kristaps 822: default:
823: break;
824: }
825: return(1);
826: }
827:
828:
829: /* ARGSUSED */
1.19 kristaps 830: static void
831: termp_sh_post(DECL_ARGS)
832: {
833:
834: switch (node->type) {
835: case (MDOC_HEAD):
836: newln(p);
837: break;
838: case (MDOC_BODY):
839: newln(p);
840: p->offset = 0;
841: break;
842: default:
843: break;
844: }
845: }
846:
847:
848: /* ARGSUSED */
1.10 kristaps 849: static int
850: termp_op_pre(DECL_ARGS)
851: {
852:
853: switch (node->type) {
854: case (MDOC_BODY):
855: word(p, "\\(lB");
856: p->flags |= TERMP_NOSPACE;
1.2 kristaps 857: break;
858: default:
1.10 kristaps 859: break;
1.2 kristaps 860: }
1.10 kristaps 861: return(1);
862: }
863:
864:
865: /* ARGSUSED */
866: static int
1.17 kristaps 867: termp_bt_pre(DECL_ARGS)
868: {
869:
870: word(p, "is currently in beta test.");
871: return(1);
872: }
873:
874:
875: /* ARGSUSED */
876: static int
1.10 kristaps 877: termp_ud_pre(DECL_ARGS)
878: {
879:
880: word(p, "currently under development.");
881: return(1);
882: }
883:
884:
885: /* ARGSUSED */
886: static int
887: termp_d1_pre(DECL_ARGS)
888: {
889:
890: if (MDOC_BODY != node->type)
891: return(1);
892: newln(p);
1.19 kristaps 893: p->offset += (pair->offset = INDENT);
1.10 kristaps 894: return(1);
1.2 kristaps 895: }
896:
897:
1.10 kristaps 898: /* ARGSUSED */
1.2 kristaps 899: static void
1.10 kristaps 900: termp_d1_post(DECL_ARGS)
901: {
902:
903: if (MDOC_BODY != node->type)
904: return;
905: newln(p);
1.19 kristaps 906: p->offset -= pair->offset;
1.10 kristaps 907: }
908:
909:
910: /* ARGSUSED */
911: static int
912: termp_aq_pre(DECL_ARGS)
1.6 kristaps 913: {
914:
1.10 kristaps 915: if (MDOC_BODY != node->type)
916: return(1);
917: word(p, "<");
918: p->flags |= TERMP_NOSPACE;
919: return(1);
920: }
1.6 kristaps 921:
922:
1.10 kristaps 923: /* ARGSUSED */
924: static void
925: termp_aq_post(DECL_ARGS)
926: {
1.6 kristaps 927:
1.10 kristaps 928: if (MDOC_BODY != node->type)
1.6 kristaps 929: return;
1.10 kristaps 930: p->flags |= TERMP_NOSPACE;
931: word(p, ">");
932: }
1.6 kristaps 933:
1.10 kristaps 934:
935: /* ARGSUSED */
936: static int
937: termp_ft_pre(DECL_ARGS)
938: {
939:
1.18 kristaps 940: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_TYPE]);
1.10 kristaps 941: return(1);
1.6 kristaps 942: }
943:
944:
1.10 kristaps 945: /* ARGSUSED */
1.6 kristaps 946: static void
1.10 kristaps 947: termp_ft_post(DECL_ARGS)
1.2 kristaps 948: {
949:
1.10 kristaps 950: if (node->sec == SEC_SYNOPSIS)
951: newln(p);
952: }
1.2 kristaps 953:
954:
1.10 kristaps 955: /* ARGSUSED */
956: static int
957: termp_fn_pre(DECL_ARGS)
958: {
959: const struct mdoc_node *n;
960:
961: assert(node->child);
962: assert(MDOC_TEXT == node->child->type);
1.2 kristaps 963:
1.10 kristaps 964: /* FIXME: can be "type funcname" "type varname"... */
1.2 kristaps 965:
1.10 kristaps 966: p->flags |= ttypes[TTYPE_FUNC_NAME];
967: word(p, node->child->data.text.string);
968: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
969:
970: word(p, "(");
971:
972: p->flags |= TERMP_NOSPACE;
973: for (n = node->child->next; n; n = n->next) {
974: assert(MDOC_TEXT == n->type);
975: p->flags |= ttypes[TTYPE_FUNC_ARG];
976: word(p, n->data.text.string);
977: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1.16 kristaps 978: if (n->next)
1.10 kristaps 979: word(p, ",");
1.6 kristaps 980: }
1.2 kristaps 981:
1.10 kristaps 982: word(p, ")");
983:
984: if (SEC_SYNOPSIS == node->sec)
985: word(p, ";");
986:
987: return(0);
1.2 kristaps 988: }
989:
990:
1.10 kristaps 991: /* ARGSUSED */
992: static void
993: termp_fn_post(DECL_ARGS)
1.2 kristaps 994: {
995:
1.30 ! kristaps 996: if (node->sec == SEC_SYNOPSIS && node->next)
1.10 kristaps 997: vspace(p);
998:
999: }
1.2 kristaps 1000:
1001:
1.10 kristaps 1002: /* ARGSUSED */
1003: static int
1004: termp_sx_pre(DECL_ARGS)
1005: {
1.8 kristaps 1006:
1.18 kristaps 1007: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_LINK]);
1.10 kristaps 1008: return(1);
1.2 kristaps 1009: }
1010:
1011:
1.10 kristaps 1012: /* ARGSUSED */
1013: static int
1014: termp_fa_pre(DECL_ARGS)
1015: {
1.16 kristaps 1016: struct mdoc_node *n;
1017:
1018: if (node->parent->tok != MDOC_Fo) {
1.18 kristaps 1019: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_ARG]);
1.16 kristaps 1020: return(1);
1021: }
1022:
1023: for (n = node->child; n; n = n->next) {
1024: assert(MDOC_TEXT == n->type);
1025:
1026: p->flags |= ttypes[TTYPE_FUNC_ARG];
1027: word(p, n->data.text.string);
1028: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1029:
1030: if (n->next)
1031: word(p, ",");
1032: }
1033:
1034: if (node->next && node->next->tok == MDOC_Fa)
1035: word(p, ",");
1.2 kristaps 1036:
1.16 kristaps 1037: return(0);
1.10 kristaps 1038: }
1.2 kristaps 1039:
1040:
1.10 kristaps 1041: /* ARGSUSED */
1042: static int
1043: termp_va_pre(DECL_ARGS)
1044: {
1.2 kristaps 1045:
1.18 kristaps 1046: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 1047: return(1);
1.2 kristaps 1048: }
1049:
1050:
1.10 kristaps 1051: /* ARGSUSED */
1052: static int
1053: termp_bd_pre(DECL_ARGS)
1054: {
1055: const struct mdoc_block *bl;
1056: const struct mdoc_node *n;
1.12 kristaps 1057: int i;
1.1 kristaps 1058:
1.10 kristaps 1059: if (MDOC_BLOCK == node->type) {
1.30 ! kristaps 1060: if (node->prev)
! 1061: vspace(p);
1.10 kristaps 1062: return(1);
1063: } else if (MDOC_BODY != node->type)
1064: return(1);
1065:
1066: assert(MDOC_BLOCK == node->parent->type);
1.20 kristaps 1067: pair->offset = p->offset;
1.10 kristaps 1068:
1069: bl = &node->parent->data.block;
1.12 kristaps 1070:
1.20 kristaps 1071:
1.12 kristaps 1072: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
1073: if (-1 != i) {
1074: assert(1 == bl->argv[i].sz);
1.20 kristaps 1075: p->offset += arg_offset(&bl->argv[i]);
1.12 kristaps 1076: }
1077:
1.10 kristaps 1078: if ( ! arg_hasattr(MDOC_Literal, bl->argc, bl->argv))
1079: return(1);
1080:
1081: p->flags |= TERMP_LITERAL;
1082:
1083: for (n = node->child; n; n = n->next) {
1084: assert(MDOC_TEXT == n->type); /* FIXME */
1085: if ((*n->data.text.string)) {
1086: word(p, n->data.text.string);
1087: flushln(p);
1088: } else
1089: vspace(p);
1.1 kristaps 1090:
1.10 kristaps 1091: }
1.1 kristaps 1092:
1.10 kristaps 1093: p->flags &= ~TERMP_LITERAL;
1094: return(0);
1095: }
1.1 kristaps 1096:
1097:
1.10 kristaps 1098: /* ARGSUSED */
1.12 kristaps 1099: static void
1100: termp_bd_post(DECL_ARGS)
1101: {
1102:
1.20 kristaps 1103: if (MDOC_BODY != node->type)
1104: return;
1105: newln(p);
1106: p->offset = pair->offset;
1.12 kristaps 1107: }
1108:
1109:
1110: /* ARGSUSED */
1.10 kristaps 1111: static int
1112: termp_qq_pre(DECL_ARGS)
1113: {
1.1 kristaps 1114:
1.10 kristaps 1115: if (MDOC_BODY != node->type)
1116: return(1);
1117: word(p, "\"");
1118: p->flags |= TERMP_NOSPACE;
1119: return(1);
1.1 kristaps 1120: }
1121:
1122:
1.10 kristaps 1123: /* ARGSUSED */
1.1 kristaps 1124: static void
1.10 kristaps 1125: termp_qq_post(DECL_ARGS)
1.1 kristaps 1126: {
1127:
1.10 kristaps 1128: if (MDOC_BODY != node->type)
1129: return;
1130: p->flags |= TERMP_NOSPACE;
1131: word(p, "\"");
1132: }
1133:
1134:
1135: /* ARGSUSED */
1136: static int
1.15 kristaps 1137: termp_bsx_pre(DECL_ARGS)
1138: {
1139:
1140: word(p, "BSDI BSD/OS");
1141: return(1);
1142: }
1143:
1144:
1145: /* ARGSUSED */
1146: static int
1.10 kristaps 1147: termp_bx_pre(DECL_ARGS)
1148: {
1.1 kristaps 1149:
1.10 kristaps 1150: word(p, "BSD");
1151: return(1);
1152: }
1153:
1154:
1155: /* ARGSUSED */
1156: static int
1157: termp_ox_pre(DECL_ARGS)
1158: {
1159:
1160: word(p, "OpenBSD");
1161: return(1);
1162: }
1163:
1164:
1165: /* ARGSUSED */
1166: static int
1.16 kristaps 1167: termp_ux_pre(DECL_ARGS)
1168: {
1169:
1170: word(p, "UNIX");
1171: return(1);
1172: }
1173:
1174:
1175: /* ARGSUSED */
1176: static int
1177: termp_fx_pre(DECL_ARGS)
1178: {
1179:
1180: word(p, "FreeBSD");
1181: return(1);
1182: }
1183:
1184:
1185: /* ARGSUSED */
1186: static int
1.10 kristaps 1187: termp_nx_pre(DECL_ARGS)
1188: {
1189:
1190: word(p, "NetBSD");
1191: return(1);
1192: }
1193:
1194:
1195: /* ARGSUSED */
1196: static int
1197: termp_sq_pre(DECL_ARGS)
1198: {
1199:
1200: if (MDOC_BODY != node->type)
1201: return(1);
1.28 kristaps 1202: word(p, "`");
1.10 kristaps 1203: p->flags |= TERMP_NOSPACE;
1204: return(1);
1205: }
1.1 kristaps 1206:
1207:
1.10 kristaps 1208: /* ARGSUSED */
1209: static void
1210: termp_sq_post(DECL_ARGS)
1211: {
1212:
1213: if (MDOC_BODY != node->type)
1214: return;
1215: p->flags |= TERMP_NOSPACE;
1216: word(p, "\'");
1217: }
1.2 kristaps 1218:
1219:
1.10 kristaps 1220: /* ARGSUSED */
1221: static int
1222: termp_pf_pre(DECL_ARGS)
1223: {
1.1 kristaps 1224:
1.10 kristaps 1225: p->flags |= TERMP_IGNDELIM;
1226: return(1);
1227: }
1.1 kristaps 1228:
1229:
1.10 kristaps 1230: /* ARGSUSED */
1231: static void
1232: termp_pf_post(DECL_ARGS)
1233: {
1.1 kristaps 1234:
1.10 kristaps 1235: p->flags &= ~TERMP_IGNDELIM;
1236: p->flags |= TERMP_NOSPACE;
1237: }
1.1 kristaps 1238:
1239:
1.10 kristaps 1240: /* ARGSUSED */
1241: static int
1242: termp_ss_pre(DECL_ARGS)
1243: {
1.1 kristaps 1244:
1.10 kristaps 1245: switch (node->type) {
1246: case (MDOC_HEAD):
1247: vspace(p);
1.18 kristaps 1248: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SSECTION]);
1.10 kristaps 1249: p->offset = INDENT / 2;
1250: break;
1251: default:
1252: break;
1253: }
1.1 kristaps 1254:
1.10 kristaps 1255: return(1);
1.1 kristaps 1256: }
1257:
1258:
1.10 kristaps 1259: /* ARGSUSED */
1260: static void
1261: termp_ss_post(DECL_ARGS)
1.1 kristaps 1262: {
1263:
1.10 kristaps 1264: switch (node->type) {
1265: case (MDOC_HEAD):
1266: newln(p);
1267: p->offset = INDENT;
1268: break;
1269: default:
1270: break;
1271: }
1272: }
1.2 kristaps 1273:
1274:
1.10 kristaps 1275: /* ARGSUSED */
1276: static int
1277: termp_pa_pre(DECL_ARGS)
1278: {
1.2 kristaps 1279:
1.18 kristaps 1280: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FILE]);
1.10 kristaps 1281: return(1);
1.1 kristaps 1282: }
1283:
1284:
1.10 kristaps 1285: /* ARGSUSED */
1.11 kristaps 1286: static int
1287: termp_em_pre(DECL_ARGS)
1288: {
1289:
1.18 kristaps 1290: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.11 kristaps 1291: return(1);
1292: }
1293:
1294:
1295: /* ARGSUSED */
1.14 kristaps 1296: static int
1297: termp_cd_pre(DECL_ARGS)
1298: {
1299:
1.18 kristaps 1300: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CONFIG]);
1.14 kristaps 1301: return(1);
1302: }
1303:
1304:
1305: /* ARGSUSED */
1306: static int
1307: termp_cm_pre(DECL_ARGS)
1308: {
1309:
1.18 kristaps 1310: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_FLAG]);
1.14 kristaps 1311: return(1);
1312: }
1313:
1314:
1315: /* ARGSUSED */
1316: static int
1317: termp_ic_pre(DECL_ARGS)
1318: {
1319:
1.18 kristaps 1320: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD]);
1.14 kristaps 1321: return(1);
1322: }
1323:
1324:
1325: /* ARGSUSED */
1326: static int
1327: termp_in_pre(DECL_ARGS)
1328: {
1329:
1.30 ! kristaps 1330: p->flags |= ttypes[TTYPE_INCLUDE];
! 1331: word(p, "#include");
! 1332: word(p, "<");
! 1333: p->flags &= ~ttypes[TTYPE_INCLUDE];
! 1334: p->flags |= TERMP_NOSPACE;
1.18 kristaps 1335: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_INCLUDE]);
1.14 kristaps 1336: return(1);
1337: }
1338:
1339:
1340: /* ARGSUSED */
1.30 ! kristaps 1341: static void
! 1342: termp_in_post(DECL_ARGS)
! 1343: {
! 1344:
! 1345: p->flags |= TERMP_NOSPACE;
! 1346: word(p, ">");
! 1347:
! 1348: newln(p);
! 1349: if (SEC_SYNOPSIS != node->sec)
! 1350: return;
! 1351: if (node->next && MDOC_In != node->next->tok)
! 1352: vspace(p);
! 1353: }
! 1354:
! 1355:
! 1356: /* ARGSUSED */
1.14 kristaps 1357: static int
1358: termp_at_pre(DECL_ARGS)
1359: {
1360: enum mdoc_att c;
1361:
1362: c = ATT_DEFAULT;
1363: if (node->child) {
1364: assert(MDOC_TEXT == node->child->type);
1365: c = mdoc_atoatt(node->child->data.text.string);
1366: }
1367:
1368: word(p, mdoc_att2a(c));
1369: return(0);
1370: }
1.15 kristaps 1371:
1372:
1373: /* ARGSUSED */
1374: static int
1375: termp_bq_pre(DECL_ARGS)
1376: {
1377:
1378: if (MDOC_BODY != node->type)
1379: return(1);
1.30 ! kristaps 1380: word(p, "[");
1.15 kristaps 1381: p->flags |= TERMP_NOSPACE;
1382: return(1);
1383: }
1384:
1385:
1386: /* ARGSUSED */
1387: static void
1388: termp_bq_post(DECL_ARGS)
1389: {
1390:
1391: if (MDOC_BODY != node->type)
1392: return;
1393: word(p, "]");
1394: }
1395:
1396:
1397: /* ARGSUSED */
1398: static int
1399: termp_pq_pre(DECL_ARGS)
1400: {
1401:
1402: if (MDOC_BODY != node->type)
1403: return(1);
1.30 ! kristaps 1404: word(p, "(");
1.15 kristaps 1405: p->flags |= TERMP_NOSPACE;
1406: return(1);
1407: }
1408:
1409:
1410: /* ARGSUSED */
1411: static void
1412: termp_pq_post(DECL_ARGS)
1413: {
1414:
1415: if (MDOC_BODY != node->type)
1416: return;
1417: word(p, ")");
1418: }
1419:
1420:
1.16 kristaps 1421: /* ARGSUSED */
1422: static int
1423: termp_fo_pre(DECL_ARGS)
1424: {
1425: const struct mdoc_node *n;
1426:
1427: if (MDOC_BODY == node->type) {
1428: word(p, "(");
1429: p->flags |= TERMP_NOSPACE;
1430: return(1);
1431: } else if (MDOC_HEAD != node->type)
1432: return(1);
1433:
1.17 kristaps 1434: /* XXX - groff shows only first parameter */
1435:
1.16 kristaps 1436: p->flags |= ttypes[TTYPE_FUNC_NAME];
1437: for (n = node->child; n; n = n->next) {
1438: assert(MDOC_TEXT == n->type);
1439: word(p, n->data.text.string);
1440: }
1441: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
1442:
1443: return(0);
1444: }
1445:
1446:
1447: /* ARGSUSED */
1448: static void
1449: termp_fo_post(DECL_ARGS)
1450: {
1451:
1452: if (MDOC_BODY != node->type)
1453: return;
1454: word(p, ")");
1455: word(p, ";");
1456: newln(p);
1457: }
1458:
1459:
1.17 kristaps 1460: /* ARGSUSED */
1461: static int
1462: termp_bf_pre(DECL_ARGS)
1463: {
1464: const struct mdoc_node *n;
1465: const struct mdoc_block *b;
1466:
1467: /* XXX - we skip over possible trailing HEAD tokens. */
1468:
1469: if (MDOC_HEAD == node->type)
1470: return(0);
1471: else if (MDOC_BLOCK != node->type)
1472: return(1);
1473:
1474: b = &node->data.block;
1475:
1476: if (NULL == (n = b->head->child)) {
1477: if (arg_hasattr(MDOC_Emphasis, b->argc, b->argv))
1.18 kristaps 1478: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1479: else if (arg_hasattr(MDOC_Symbolic, b->argc, b->argv))
1.18 kristaps 1480: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1481:
1482: return(1);
1483: }
1484:
1485: assert(MDOC_TEXT == n->type);
1486:
1487: if (0 == strcmp("Em", n->data.text.string))
1.18 kristaps 1488: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1489: else if (0 == strcmp("Sy", n->data.text.string))
1.18 kristaps 1490: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1491:
1492: return(1);
1493: }
1494:
1495:
1496: /* ARGSUSED */
1497: static int
1498: termp_sy_pre(DECL_ARGS)
1499: {
1500:
1.18 kristaps 1501: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1502: return(1);
1503: }
1504:
1505:
1506: /* ARGSUSED */
1507: static int
1508: termp_ms_pre(DECL_ARGS)
1509: {
1510:
1.18 kristaps 1511: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMBOL]);
1.17 kristaps 1512: return(1);
1513: }
1514:
1.22 kristaps 1515:
1516:
1517: /* ARGSUSED */
1518: static int
1519: termp_sm_pre(DECL_ARGS)
1520: {
1521:
1522: #if notyet
1523: assert(node->child);
1524: if (0 == strcmp("off", node->child->data.text.string)) {
1525: p->flags &= ~TERMP_NONOSPACE;
1526: p->flags &= ~TERMP_NOSPACE;
1527: } else {
1528: p->flags |= TERMP_NONOSPACE;
1529: p->flags |= TERMP_NOSPACE;
1530: }
1531: #endif
1532:
1533: return(0);
1534: }
1.28 kristaps 1535:
1536:
1537: /* ARGSUSED */
1538: static int
1539: termp__t_pre(DECL_ARGS)
1540: {
1541:
1542: word(p, "\"");
1543: p->flags |= TERMP_NOSPACE;
1544: return(1);
1545: }
1546:
1547:
1548: /* ARGSUSED */
1549: static void
1550: termp__t_post(DECL_ARGS)
1551: {
1552:
1553: p->flags |= TERMP_NOSPACE;
1554: word(p, "\"");
1555: word(p, node->next ? "," : ".");
1556: }
1557:
1558:
1559: /* ARGSUSED */
1560: static void
1561: termp____post(DECL_ARGS)
1562: {
1563:
1564: p->flags |= TERMP_NOSPACE;
1565: word(p, node->next ? "," : ".");
1566: }
CVSweb