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