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