Annotation of mandoc/term.c, Revision 1.23
1.23 ! kristaps 1: /* $Id: term.c,v 1.22 2009/02/25 17:02:47 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:
! 384: for (i = 0; i < (int)bl->argc; i++)
! 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_Item):
! 395: /* FALLTHROUGH */
! 396: case (MDOC_Tag):
! 397: /* FALLTHROUGH */
! 398: case (MDOC_Ohang):
! 399: type = bl->argv[i].arg;
! 400: i = (int)bl->argc;
! 401: break;
! 402: case (MDOC_Inset):
! 403: /* FALLTHROUGH */
! 404: case (MDOC_Hang):
! 405: /* FALLTHROUGH */
! 406: case (MDOC_Diag):
! 407: /* FALLTHROUGH */
! 408: case (MDOC_Column):
! 409: errx(1, "list type not supported");
! 410: /* NOTREACHED */
! 411: default:
! 412: break;
! 413: }
! 414:
! 415: /* Save our existing (inherited) margin and offset. */
! 416:
1.20 kristaps 417: pair->offset = p->offset;
418: pair->rmargin = p->rmargin;
419:
1.23 ! kristaps 420: /* Get list width and offset. */
! 421:
1.20 kristaps 422: /* FIXME: auto-size. */
423: i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
1.23 ! kristaps 424: width = i >= 0 ? arg_width(&bl->argv[i]) : 0;
1.20 kristaps 425:
426: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
427: offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0;
428:
1.23 ! kristaps 429: /* Override the width. */
1.10 kristaps 430:
1.23 ! kristaps 431: switch (type) {
! 432: case (MDOC_Bullet):
! 433: /* FALLTHROUGH */
! 434: case (MDOC_Dash):
! 435: /* FALLTHROUGH */
! 436: case (MDOC_Enum):
! 437: /* FALLTHROUGH */
! 438: case (MDOC_Hyphen):
! 439: width = width > 6 ? width : 6;
! 440: break;
! 441: case (MDOC_Tag):
! 442: if (0 == width)
! 443: errx(1, "need non-zero -width");
! 444: break;
! 445: default:
! 446: break;
! 447: }
1.10 kristaps 448:
1.23 ! kristaps 449: /* Word-wrap control. */
1.21 kristaps 450:
1.23 ! kristaps 451: p->flags |= TERMP_NOSPACE;
1.21 kristaps 452:
1.23 ! kristaps 453: switch (type) {
! 454: case (MDOC_Bullet):
! 455: /* FALLTHROUGH */
! 456: case (MDOC_Dash):
! 457: /* FALLTHROUGH */
! 458: case (MDOC_Enum):
! 459: /* FALLTHROUGH */
! 460: case (MDOC_Hyphen):
! 461: /* FALLTHROUGH */
! 462: case (MDOC_Tag):
! 463: if (MDOC_HEAD == node->type)
! 464: p->flags |= TERMP_NOBREAK;
! 465: else if (MDOC_BODY == node->type)
! 466: p->flags |= TERMP_NOLPAD;
! 467: break;
! 468: case (MDOC_Ohang):
! 469: break;
! 470: }
1.21 kristaps 471:
1.23 ! kristaps 472: /*
! 473: * Get a token to use as the HEAD lead-in. If NULL, we use the
! 474: * HEAD child.
! 475: */
1.21 kristaps 476:
1.23 ! kristaps 477: tp = NULL;
! 478: if (MDOC_HEAD == node->type) {
! 479: if (arg_hasattr(MDOC_Bullet, bl->argc, bl->argv))
! 480: tp = "\\[bu]";
! 481: if (arg_hasattr(MDOC_Dash, bl->argc, bl->argv))
! 482: tp = "\\-";
! 483: if (arg_hasattr(MDOC_Enum, bl->argc, bl->argv)) {
1.21 kristaps 484: (pair->ppair->ppair->count)++;
485: (void)snprintf(buf, sizeof(buf), "%d.",
486: pair->ppair->ppair->count);
1.23 ! kristaps 487: tp = buf;
1.2 kristaps 488: }
1.23 ! kristaps 489: if (arg_hasattr(MDOC_Hyphen, bl->argc, bl->argv))
! 490: tp = "\\-";
! 491: if (arg_hasattr(MDOC_Item, bl->argc, bl->argv))
! 492: tp = "";
! 493: }
1.20 kristaps 494:
1.23 ! kristaps 495: /* Margin control. */
1.2 kristaps 496:
1.21 kristaps 497: p->offset += offset;
1.23 ! kristaps 498:
! 499: switch (type) {
! 500: case (MDOC_Bullet):
! 501: /* FALLTHROUGH */
! 502: case (MDOC_Dash):
! 503: /* FALLTHROUGH */
! 504: case (MDOC_Enum):
! 505: /* FALLTHROUGH */
! 506: case (MDOC_Hyphen):
! 507: /* FALLTHROUGH */
! 508: case (MDOC_Item):
! 509: /* FALLTHROUGH */
! 510: case (MDOC_Tag):
! 511: if (MDOC_HEAD == node->type)
! 512: p->rmargin = p->offset + width;
! 513: else if (MDOC_BODY == node->type)
! 514: p->offset += width;
! 515: break;
! 516: case (MDOC_Ohang):
! 517: break;
! 518: }
! 519:
! 520: if (NULL == tp)
! 521: return(1);
! 522:
! 523: /* XXX - ignoring children. */
! 524:
! 525: word(p, tp);
! 526: return(0);
1.10 kristaps 527: }
528:
529:
530: /* ARGSUSED */
1.20 kristaps 531: static void
532: termp_it_post(DECL_ARGS)
1.10 kristaps 533: {
1.3 kristaps 534:
1.21 kristaps 535: if (MDOC_BODY != node->type && MDOC_HEAD != node->type)
1.20 kristaps 536: return;
1.10 kristaps 537:
1.23 ! kristaps 538: flushln(p);
1.10 kristaps 539:
1.23 ! kristaps 540: p->offset = pair->offset;
! 541: p->rmargin = pair->rmargin;
1.21 kristaps 542:
1.23 ! kristaps 543: if (MDOC_HEAD == node->type) {
! 544: p->flags &= ~TERMP_NOBREAK;
! 545: p->flags &= ~TERMP_NORPAD;
! 546: } else if (MDOC_BODY == node->type)
! 547: p->flags &= ~TERMP_NOLPAD;
1.2 kristaps 548: }
549:
550:
1.10 kristaps 551: /* ARGSUSED */
1.18 kristaps 552: static int
553: termp_nm_pre(DECL_ARGS)
1.10 kristaps 554: {
555:
1.18 kristaps 556: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_PROG]);
557: if (NULL == node->child)
558: word(p, meta->name);
559: return(1);
1.10 kristaps 560: }
561:
562:
563: /* ARGSUSED */
1.18 kristaps 564: static int
565: termp_fl_pre(DECL_ARGS)
1.10 kristaps 566: {
567:
1.18 kristaps 568: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_FLAG]);
569: word(p, "\\-");
570: p->flags |= TERMP_NOSPACE;
571: return(1);
1.10 kristaps 572: }
573:
574:
575: /* ARGSUSED */
576: static int
577: termp_ar_pre(DECL_ARGS)
578: {
579:
1.18 kristaps 580: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_ARG]);
1.10 kristaps 581: if (NULL == node->child)
582: word(p, "...");
583: return(1);
584: }
585:
586:
587: /* ARGSUSED */
588: static int
589: termp_ns_pre(DECL_ARGS)
1.2 kristaps 590: {
591:
592: p->flags |= TERMP_NOSPACE;
1.10 kristaps 593: return(1);
594: }
595:
596:
597: /* ARGSUSED */
598: static int
599: termp_pp_pre(DECL_ARGS)
600: {
601:
602: vspace(p);
603: return(1);
604: }
605:
606:
607: /* ARGSUSED */
608: static int
1.14 kristaps 609: termp_st_pre(DECL_ARGS)
610: {
611: const char *tp;
612:
613: assert(1 == node->data.elem.argc);
614:
615: tp = mdoc_st2a(node->data.elem.argv[0].arg);
616: word(p, tp);
617:
618: return(1);
619: }
620:
621:
622: /* ARGSUSED */
623: static int
624: termp_rv_pre(DECL_ARGS)
625: {
626: int i;
627:
628: i = arg_getattr(MDOC_Std, node->data.elem.argc,
629: node->data.elem.argv);
630: assert(i >= 0);
631:
632: newln(p);
633: word(p, "The");
634:
635: p->flags |= ttypes[TTYPE_FUNC_NAME];
636: word(p, *node->data.elem.argv[i].value);
637: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
638:
639: word(p, "() function returns the value 0 if successful;");
640: word(p, "otherwise the value -1 is returned and the");
641: word(p, "global variable");
642:
643: p->flags |= ttypes[TTYPE_VAR_DECL];
644: word(p, "errno");
645: p->flags &= ~ttypes[TTYPE_VAR_DECL];
646:
647: word(p, "is set to indicate the error.");
648:
649: return(1);
650: }
651:
652:
653: /* ARGSUSED */
654: static int
1.10 kristaps 655: termp_ex_pre(DECL_ARGS)
656: {
657: int i;
658:
659: i = arg_getattr(MDOC_Std, node->data.elem.argc,
660: node->data.elem.argv);
661: assert(i >= 0);
662:
663: word(p, "The");
664: p->flags |= ttypes[TTYPE_PROG];
665: word(p, *node->data.elem.argv[i].value);
666: p->flags &= ~ttypes[TTYPE_PROG];
667: word(p, "utility exits 0 on success, and >0 if an error occurs.");
668:
669: return(1);
670: }
671:
672:
673: /* ARGSUSED */
674: static int
675: termp_nd_pre(DECL_ARGS)
676: {
677:
678: word(p, "\\-");
679: return(1);
680: }
681:
682:
683: /* ARGSUSED */
684: static void
685: termp_bl_post(DECL_ARGS)
686: {
687:
688: if (MDOC_BLOCK == node->type)
689: newln(p);
690: }
691:
692:
693: /* ARGSUSED */
694: static void
695: termp_op_post(DECL_ARGS)
696: {
697:
698: if (MDOC_BODY != node->type)
1.2 kristaps 699: return;
1.10 kristaps 700: p->flags |= TERMP_NOSPACE;
701: word(p, "\\(rB");
702: }
703:
704:
705: /* ARGSUSED */
706: static int
707: termp_xr_pre(DECL_ARGS)
708: {
709: const struct mdoc_node *n;
710:
711: n = node->child;
712: assert(n);
713:
714: assert(MDOC_TEXT == n->type);
715: word(p, n->data.text.string);
716:
717: if (NULL == (n = n->next))
718: return(0);
719:
720: assert(MDOC_TEXT == n->type);
721: p->flags |= TERMP_NOSPACE;
722: word(p, "(");
723: p->flags |= TERMP_NOSPACE;
724: word(p, n->data.text.string);
725: p->flags |= TERMP_NOSPACE;
726: word(p, ")");
727:
728: return(0);
1.2 kristaps 729: }
730:
731:
1.10 kristaps 732: /* ARGSUSED */
733: static int
734: termp_vt_pre(DECL_ARGS)
1.2 kristaps 735: {
736:
1.10 kristaps 737: /* FIXME: this can be "type name". */
1.18 kristaps 738: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 739: return(1);
1.2 kristaps 740: }
741:
742:
1.10 kristaps 743: /* ARGSUSED */
1.2 kristaps 744: static void
1.10 kristaps 745: termp_vt_post(DECL_ARGS)
746: {
747:
748: if (node->sec == SEC_SYNOPSIS)
749: vspace(p);
750: }
751:
752:
753: /* ARGSUSED */
754: static int
755: termp_fd_pre(DECL_ARGS)
1.2 kristaps 756: {
757:
1.10 kristaps 758: /*
759: * FIXME: this naming is bad. This value is used, in general,
760: * for the #include header or other preprocessor statement.
761: */
1.18 kristaps 762: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_DECL]);
1.10 kristaps 763: return(1);
1.2 kristaps 764: }
765:
766:
1.10 kristaps 767: /* ARGSUSED */
1.2 kristaps 768: static void
1.10 kristaps 769: termp_fd_post(DECL_ARGS)
1.2 kristaps 770: {
771:
1.10 kristaps 772: if (node->sec == SEC_SYNOPSIS)
773: vspace(p);
774: }
775:
776:
777: /* ARGSUSED */
778: static int
779: termp_sh_pre(DECL_ARGS)
780: {
1.2 kristaps 781:
1.10 kristaps 782: switch (node->type) {
783: case (MDOC_HEAD):
784: vspace(p);
1.18 kristaps 785: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SECTION]);
1.2 kristaps 786: break;
1.10 kristaps 787: case (MDOC_BODY):
788: p->offset = INDENT;
1.2 kristaps 789: break;
1.10 kristaps 790: default:
791: break;
792: }
793: return(1);
794: }
795:
796:
797: /* ARGSUSED */
1.19 kristaps 798: static void
799: termp_sh_post(DECL_ARGS)
800: {
801:
802: switch (node->type) {
803: case (MDOC_HEAD):
804: newln(p);
805: break;
806: case (MDOC_BODY):
807: newln(p);
808: p->offset = 0;
809: break;
810: default:
811: break;
812: }
813: }
814:
815:
816: /* ARGSUSED */
1.10 kristaps 817: static int
818: termp_op_pre(DECL_ARGS)
819: {
820:
821: switch (node->type) {
822: case (MDOC_BODY):
823: word(p, "\\(lB");
824: p->flags |= TERMP_NOSPACE;
1.2 kristaps 825: break;
826: default:
1.10 kristaps 827: break;
1.2 kristaps 828: }
1.10 kristaps 829: return(1);
830: }
831:
832:
833: /* ARGSUSED */
834: static int
1.17 kristaps 835: termp_bt_pre(DECL_ARGS)
836: {
837:
838: word(p, "is currently in beta test.");
839: return(1);
840: }
841:
842:
843: /* ARGSUSED */
844: static int
1.10 kristaps 845: termp_ud_pre(DECL_ARGS)
846: {
847:
848: word(p, "currently under development.");
849: return(1);
850: }
851:
852:
853: /* ARGSUSED */
854: static int
855: termp_d1_pre(DECL_ARGS)
856: {
857:
858: if (MDOC_BODY != node->type)
859: return(1);
860: newln(p);
1.19 kristaps 861: p->offset += (pair->offset = INDENT);
1.10 kristaps 862: return(1);
1.2 kristaps 863: }
864:
865:
1.10 kristaps 866: /* ARGSUSED */
1.2 kristaps 867: static void
1.10 kristaps 868: termp_d1_post(DECL_ARGS)
869: {
870:
871: if (MDOC_BODY != node->type)
872: return;
873: newln(p);
1.19 kristaps 874: p->offset -= pair->offset;
1.10 kristaps 875: }
876:
877:
878: /* ARGSUSED */
879: static int
880: termp_aq_pre(DECL_ARGS)
1.6 kristaps 881: {
882:
1.10 kristaps 883: if (MDOC_BODY != node->type)
884: return(1);
885: word(p, "<");
886: p->flags |= TERMP_NOSPACE;
887: return(1);
888: }
1.6 kristaps 889:
890:
1.10 kristaps 891: /* ARGSUSED */
892: static void
893: termp_aq_post(DECL_ARGS)
894: {
1.6 kristaps 895:
1.10 kristaps 896: if (MDOC_BODY != node->type)
1.6 kristaps 897: return;
1.10 kristaps 898: p->flags |= TERMP_NOSPACE;
899: word(p, ">");
900: }
1.6 kristaps 901:
1.10 kristaps 902:
903: /* ARGSUSED */
904: static int
905: termp_ft_pre(DECL_ARGS)
906: {
907:
1.18 kristaps 908: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_TYPE]);
1.10 kristaps 909: return(1);
1.6 kristaps 910: }
911:
912:
1.10 kristaps 913: /* ARGSUSED */
1.6 kristaps 914: static void
1.10 kristaps 915: termp_ft_post(DECL_ARGS)
1.2 kristaps 916: {
917:
1.10 kristaps 918: if (node->sec == SEC_SYNOPSIS)
919: newln(p);
920: }
1.2 kristaps 921:
922:
1.10 kristaps 923: /* ARGSUSED */
924: static int
925: termp_fn_pre(DECL_ARGS)
926: {
927: const struct mdoc_node *n;
928:
929: assert(node->child);
930: assert(MDOC_TEXT == node->child->type);
1.2 kristaps 931:
1.10 kristaps 932: /* FIXME: can be "type funcname" "type varname"... */
1.2 kristaps 933:
1.10 kristaps 934: p->flags |= ttypes[TTYPE_FUNC_NAME];
935: word(p, node->child->data.text.string);
936: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
937:
938: word(p, "(");
939:
940: p->flags |= TERMP_NOSPACE;
941: for (n = node->child->next; n; n = n->next) {
942: assert(MDOC_TEXT == n->type);
943: p->flags |= ttypes[TTYPE_FUNC_ARG];
944: word(p, n->data.text.string);
945: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1.16 kristaps 946: if (n->next)
1.10 kristaps 947: word(p, ",");
1.6 kristaps 948: }
1.2 kristaps 949:
1.10 kristaps 950: word(p, ")");
951:
952: if (SEC_SYNOPSIS == node->sec)
953: word(p, ";");
954:
955: return(0);
1.2 kristaps 956: }
957:
958:
1.10 kristaps 959: /* ARGSUSED */
960: static void
961: termp_fn_post(DECL_ARGS)
1.2 kristaps 962: {
963:
1.10 kristaps 964: if (node->sec == SEC_SYNOPSIS)
965: vspace(p);
966:
967: }
1.2 kristaps 968:
969:
1.10 kristaps 970: /* ARGSUSED */
971: static int
972: termp_sx_pre(DECL_ARGS)
973: {
1.8 kristaps 974:
1.18 kristaps 975: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_LINK]);
1.10 kristaps 976: return(1);
1.2 kristaps 977: }
978:
979:
1.10 kristaps 980: /* ARGSUSED */
981: static int
982: termp_fa_pre(DECL_ARGS)
983: {
1.16 kristaps 984: struct mdoc_node *n;
985:
986: if (node->parent->tok != MDOC_Fo) {
1.18 kristaps 987: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_ARG]);
1.16 kristaps 988: return(1);
989: }
990:
991: for (n = node->child; n; n = n->next) {
992: assert(MDOC_TEXT == n->type);
993:
994: p->flags |= ttypes[TTYPE_FUNC_ARG];
995: word(p, n->data.text.string);
996: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
997:
998: if (n->next)
999: word(p, ",");
1000: }
1001:
1002: if (node->next && node->next->tok == MDOC_Fa)
1003: word(p, ",");
1.2 kristaps 1004:
1.16 kristaps 1005: return(0);
1.10 kristaps 1006: }
1.2 kristaps 1007:
1008:
1.10 kristaps 1009: /* ARGSUSED */
1010: static int
1011: termp_va_pre(DECL_ARGS)
1012: {
1.2 kristaps 1013:
1.18 kristaps 1014: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 1015: return(1);
1.2 kristaps 1016: }
1017:
1018:
1.10 kristaps 1019: /* ARGSUSED */
1020: static int
1021: termp_bd_pre(DECL_ARGS)
1022: {
1023: const struct mdoc_block *bl;
1024: const struct mdoc_node *n;
1.12 kristaps 1025: int i;
1.1 kristaps 1026:
1.10 kristaps 1027: if (MDOC_BLOCK == node->type) {
1028: vspace(p);
1029: return(1);
1030: } else if (MDOC_BODY != node->type)
1031: return(1);
1032:
1033: assert(MDOC_BLOCK == node->parent->type);
1.20 kristaps 1034: pair->offset = p->offset;
1.10 kristaps 1035:
1036: bl = &node->parent->data.block;
1.12 kristaps 1037:
1.20 kristaps 1038:
1.12 kristaps 1039: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
1040: if (-1 != i) {
1041: assert(1 == bl->argv[i].sz);
1.20 kristaps 1042: p->offset += arg_offset(&bl->argv[i]);
1.12 kristaps 1043: }
1044:
1.10 kristaps 1045: if ( ! arg_hasattr(MDOC_Literal, bl->argc, bl->argv))
1046: return(1);
1047:
1048: p->flags |= TERMP_LITERAL;
1049:
1050: for (n = node->child; n; n = n->next) {
1051: assert(MDOC_TEXT == n->type); /* FIXME */
1052: if ((*n->data.text.string)) {
1053: word(p, n->data.text.string);
1054: flushln(p);
1055: } else
1056: vspace(p);
1.1 kristaps 1057:
1.10 kristaps 1058: }
1.1 kristaps 1059:
1.10 kristaps 1060: p->flags &= ~TERMP_LITERAL;
1061: return(0);
1062: }
1.1 kristaps 1063:
1064:
1.10 kristaps 1065: /* ARGSUSED */
1.12 kristaps 1066: static void
1067: termp_bd_post(DECL_ARGS)
1068: {
1069:
1.20 kristaps 1070: if (MDOC_BODY != node->type)
1071: return;
1072: newln(p);
1073: p->offset = pair->offset;
1.12 kristaps 1074: }
1075:
1076:
1077: /* ARGSUSED */
1.10 kristaps 1078: static int
1079: termp_qq_pre(DECL_ARGS)
1080: {
1.1 kristaps 1081:
1.10 kristaps 1082: if (MDOC_BODY != node->type)
1083: return(1);
1084: word(p, "\"");
1085: p->flags |= TERMP_NOSPACE;
1086: return(1);
1.1 kristaps 1087: }
1088:
1089:
1.10 kristaps 1090: /* ARGSUSED */
1.1 kristaps 1091: static void
1.10 kristaps 1092: termp_qq_post(DECL_ARGS)
1.1 kristaps 1093: {
1094:
1.10 kristaps 1095: if (MDOC_BODY != node->type)
1096: return;
1097: p->flags |= TERMP_NOSPACE;
1098: word(p, "\"");
1099: }
1100:
1101:
1102: /* ARGSUSED */
1103: static int
1.15 kristaps 1104: termp_bsx_pre(DECL_ARGS)
1105: {
1106:
1107: word(p, "BSDI BSD/OS");
1108: return(1);
1109: }
1110:
1111:
1112: /* ARGSUSED */
1113: static int
1.10 kristaps 1114: termp_bx_pre(DECL_ARGS)
1115: {
1.1 kristaps 1116:
1.10 kristaps 1117: word(p, "BSD");
1118: return(1);
1119: }
1120:
1121:
1122: /* ARGSUSED */
1123: static int
1124: termp_ox_pre(DECL_ARGS)
1125: {
1126:
1127: word(p, "OpenBSD");
1128: return(1);
1129: }
1130:
1131:
1132: /* ARGSUSED */
1133: static int
1.16 kristaps 1134: termp_ux_pre(DECL_ARGS)
1135: {
1136:
1137: word(p, "UNIX");
1138: return(1);
1139: }
1140:
1141:
1142: /* ARGSUSED */
1143: static int
1144: termp_fx_pre(DECL_ARGS)
1145: {
1146:
1147: word(p, "FreeBSD");
1148: return(1);
1149: }
1150:
1151:
1152: /* ARGSUSED */
1153: static int
1.10 kristaps 1154: termp_nx_pre(DECL_ARGS)
1155: {
1156:
1157: word(p, "NetBSD");
1158: return(1);
1159: }
1160:
1161:
1162: /* ARGSUSED */
1163: static int
1164: termp_sq_pre(DECL_ARGS)
1165: {
1166:
1167: if (MDOC_BODY != node->type)
1168: return(1);
1.13 kristaps 1169: word(p, "\'");
1.10 kristaps 1170: p->flags |= TERMP_NOSPACE;
1171: return(1);
1172: }
1.1 kristaps 1173:
1174:
1.10 kristaps 1175: /* ARGSUSED */
1176: static void
1177: termp_sq_post(DECL_ARGS)
1178: {
1179:
1180: if (MDOC_BODY != node->type)
1181: return;
1182: p->flags |= TERMP_NOSPACE;
1183: word(p, "\'");
1184: }
1.2 kristaps 1185:
1186:
1.10 kristaps 1187: /* ARGSUSED */
1188: static int
1189: termp_pf_pre(DECL_ARGS)
1190: {
1.1 kristaps 1191:
1.10 kristaps 1192: p->flags |= TERMP_IGNDELIM;
1193: return(1);
1194: }
1.1 kristaps 1195:
1196:
1.10 kristaps 1197: /* ARGSUSED */
1198: static void
1199: termp_pf_post(DECL_ARGS)
1200: {
1.1 kristaps 1201:
1.10 kristaps 1202: p->flags &= ~TERMP_IGNDELIM;
1203: p->flags |= TERMP_NOSPACE;
1204: }
1.1 kristaps 1205:
1206:
1.10 kristaps 1207: /* ARGSUSED */
1208: static int
1209: termp_ss_pre(DECL_ARGS)
1210: {
1.1 kristaps 1211:
1.10 kristaps 1212: switch (node->type) {
1213: case (MDOC_HEAD):
1214: vspace(p);
1.18 kristaps 1215: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SSECTION]);
1.10 kristaps 1216: p->offset = INDENT / 2;
1217: break;
1218: default:
1219: break;
1220: }
1.1 kristaps 1221:
1.10 kristaps 1222: return(1);
1.1 kristaps 1223: }
1224:
1225:
1.10 kristaps 1226: /* ARGSUSED */
1227: static void
1228: termp_ss_post(DECL_ARGS)
1.1 kristaps 1229: {
1230:
1.10 kristaps 1231: switch (node->type) {
1232: case (MDOC_HEAD):
1233: newln(p);
1234: p->offset = INDENT;
1235: break;
1236: default:
1237: break;
1238: }
1239: }
1.2 kristaps 1240:
1241:
1.10 kristaps 1242: /* ARGSUSED */
1243: static int
1244: termp_pa_pre(DECL_ARGS)
1245: {
1.2 kristaps 1246:
1.18 kristaps 1247: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FILE]);
1.10 kristaps 1248: return(1);
1.1 kristaps 1249: }
1250:
1251:
1.10 kristaps 1252: /* ARGSUSED */
1.11 kristaps 1253: static int
1254: termp_em_pre(DECL_ARGS)
1255: {
1256:
1.18 kristaps 1257: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.11 kristaps 1258: return(1);
1259: }
1260:
1261:
1262: /* ARGSUSED */
1.14 kristaps 1263: static int
1264: termp_cd_pre(DECL_ARGS)
1265: {
1266:
1.18 kristaps 1267: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CONFIG]);
1.14 kristaps 1268: return(1);
1269: }
1270:
1271:
1272: /* ARGSUSED */
1273: static int
1274: termp_cm_pre(DECL_ARGS)
1275: {
1276:
1.18 kristaps 1277: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_FLAG]);
1.14 kristaps 1278: return(1);
1279: }
1280:
1281:
1282: /* ARGSUSED */
1283: static int
1284: termp_ic_pre(DECL_ARGS)
1285: {
1286:
1.18 kristaps 1287: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD]);
1.14 kristaps 1288: return(1);
1289: }
1290:
1291:
1292: /* ARGSUSED */
1293: static int
1294: termp_in_pre(DECL_ARGS)
1295: {
1296:
1.18 kristaps 1297: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_INCLUDE]);
1.14 kristaps 1298: return(1);
1299: }
1300:
1301:
1302: /* ARGSUSED */
1303: static int
1304: termp_at_pre(DECL_ARGS)
1305: {
1306: enum mdoc_att c;
1307:
1308: c = ATT_DEFAULT;
1309: if (node->child) {
1310: assert(MDOC_TEXT == node->child->type);
1311: c = mdoc_atoatt(node->child->data.text.string);
1312: }
1313:
1314: word(p, mdoc_att2a(c));
1315: return(0);
1316: }
1.15 kristaps 1317:
1318:
1319: /* ARGSUSED */
1320: static int
1321: termp_bq_pre(DECL_ARGS)
1322: {
1323:
1324: if (MDOC_BODY != node->type)
1325: return(1);
1326: word(p, "[");
1327: p->flags |= TERMP_NOSPACE;
1328: return(1);
1329: }
1330:
1331:
1332: /* ARGSUSED */
1333: static void
1334: termp_bq_post(DECL_ARGS)
1335: {
1336:
1337: if (MDOC_BODY != node->type)
1338: return;
1339: word(p, "]");
1340: }
1341:
1342:
1343: /* ARGSUSED */
1344: static int
1345: termp_pq_pre(DECL_ARGS)
1346: {
1347:
1348: if (MDOC_BODY != node->type)
1349: return(1);
1350: word(p, "(");
1351: p->flags |= TERMP_NOSPACE;
1352: return(1);
1353: }
1354:
1355:
1356: /* ARGSUSED */
1357: static void
1358: termp_pq_post(DECL_ARGS)
1359: {
1360:
1361: if (MDOC_BODY != node->type)
1362: return;
1363: word(p, ")");
1364: }
1365:
1366:
1.16 kristaps 1367: /* ARGSUSED */
1368: static int
1369: termp_fo_pre(DECL_ARGS)
1370: {
1371: const struct mdoc_node *n;
1372:
1373: if (MDOC_BODY == node->type) {
1374: word(p, "(");
1375: p->flags |= TERMP_NOSPACE;
1376: return(1);
1377: } else if (MDOC_HEAD != node->type)
1378: return(1);
1379:
1.17 kristaps 1380: /* XXX - groff shows only first parameter */
1381:
1.16 kristaps 1382: p->flags |= ttypes[TTYPE_FUNC_NAME];
1383: for (n = node->child; n; n = n->next) {
1384: assert(MDOC_TEXT == n->type);
1385: word(p, n->data.text.string);
1386: }
1387: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
1388:
1389: return(0);
1390: }
1391:
1392:
1393: /* ARGSUSED */
1394: static void
1395: termp_fo_post(DECL_ARGS)
1396: {
1397:
1398: if (MDOC_BODY != node->type)
1399: return;
1400: word(p, ")");
1401: word(p, ";");
1402: newln(p);
1403: }
1404:
1405:
1.17 kristaps 1406: /* ARGSUSED */
1407: static int
1408: termp_bf_pre(DECL_ARGS)
1409: {
1410: const struct mdoc_node *n;
1411: const struct mdoc_block *b;
1412:
1413: /* XXX - we skip over possible trailing HEAD tokens. */
1414:
1415: if (MDOC_HEAD == node->type)
1416: return(0);
1417: else if (MDOC_BLOCK != node->type)
1418: return(1);
1419:
1420: b = &node->data.block;
1421:
1422: if (NULL == (n = b->head->child)) {
1423: if (arg_hasattr(MDOC_Emphasis, b->argc, b->argv))
1.18 kristaps 1424: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1425: else if (arg_hasattr(MDOC_Symbolic, b->argc, b->argv))
1.18 kristaps 1426: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1427:
1428: return(1);
1429: }
1430:
1431: assert(MDOC_TEXT == n->type);
1432:
1433: if (0 == strcmp("Em", n->data.text.string))
1.18 kristaps 1434: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1435: else if (0 == strcmp("Sy", n->data.text.string))
1.18 kristaps 1436: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1437:
1438: return(1);
1439: }
1440:
1441:
1442: /* ARGSUSED */
1443: static int
1444: termp_sy_pre(DECL_ARGS)
1445: {
1446:
1.18 kristaps 1447: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1448: return(1);
1449: }
1450:
1451:
1452: /* ARGSUSED */
1453: static int
1454: termp_ms_pre(DECL_ARGS)
1455: {
1456:
1.18 kristaps 1457: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMBOL]);
1.17 kristaps 1458: return(1);
1459: }
1460:
1.22 kristaps 1461:
1462:
1463: /* ARGSUSED */
1464: static int
1465: termp_sm_pre(DECL_ARGS)
1466: {
1467:
1468: #if notyet
1469: assert(node->child);
1470: if (0 == strcmp("off", node->child->data.text.string)) {
1471: p->flags &= ~TERMP_NONOSPACE;
1472: p->flags &= ~TERMP_NOSPACE;
1473: } else {
1474: p->flags |= TERMP_NONOSPACE;
1475: p->flags |= TERMP_NOSPACE;
1476: }
1477: #endif
1478:
1479: return(0);
1480: }
CVSweb